歷屆試題 矩陣翻硬幣

2021-07-10 07:44:05 字數 2172 閱讀 6604

問題描述

小明先把硬幣擺成了乙個 n 行 m 列的矩陣。

隨後,小明對每乙個硬幣分別進行一次 q 操作。

對第x行第y列的硬幣進行 q 操作的定義:將所有第 i*x 行,第 j*y 列的硬幣進行翻轉。

其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。

當小明對所有硬幣都進行了一次 q 操作後,他發現了乙個奇蹟——所有硬幣均為正面朝上。

小明想知道最開始有多少枚硬幣是反面朝上的。於是,他向他的好朋友小m尋求幫助。

聰明的小m告訴小明,只需要對所有硬幣再進行一次q操作,即可恢復到最開始的狀態。然而小明很懶,不願意照做。於是小明希望你給出他更好的方法。幫他計算出答案。

輸入格式

輸入資料報含一行,兩個正整數 n m,含義見題目描述。

輸出格式

輸出乙個正整數,表示最開始有多少枚硬幣是反面朝上的。

樣例輸入

2 3樣例輸出

1資料規模和約定

對於10%的資料,n、m <= 10^3;

對於20%的資料,n、m <= 10^7;

對於40%的資料,n、m <= 10^15;

對於10%的資料,n、m <= 10^1000(10的1000次方)。

問題分析:根據題意要求反面朝上的硬幣的數目,即需要求翻動次數為奇數的硬幣的數量。因為初始狀態所有硬幣都是正面朝上,翻動次數為奇數,則最終反面朝上。翻動次數為偶數,則最終正面朝上。假設硬幣所在位置(i,j),要求硬幣的翻動次數。即要求(i的約數的個數)*(j的約數的個數)。兩個數相乘要結果為奇數,只能是兩個奇數相乘。故要尋找i的約數個數為奇數並且j的約數個數為奇數的點(i,j)。一般數的約數個數為偶數,因為約數一般都是成對出現的。只有完全平方數的約數個數為奇數(因為有兩個相同的約數,其餘約數都是成對出現的)。因此,要尋找的點(i,j)是i是完全平方數,j也是完全平方數。給定乙個數m,在1~m範圍內,完全平方數的個數為sqrt(m).故本題即要求sqrt(m)*sqrt(n).因為m,n的範圍比較大,涉及到大數操作。 

大數求根演算法:給定乙個數n,它的位數是len,如果len為偶數,則他的平方根的位數為len/2.如果len為奇數,那麼它的平方根的位數為len/2+1.

知道了位數之後,即可從高位到低位計算平方根。比如要求250的平方根。平方根的位數為2.

首先求最高位

(1)10*10=100<250

(2)20*20=400>250(故最高位為1)

再求次高位

(3)11*11=121<250

(4)12*12=144<250

。。。。。

(5)15*15=225<250

(6)16*16=256>250(故次高位為5)

結果為15.

以此類推,直到求到最低位。(源至

至於執行一次q翻轉過程,詳細過程這個部落格有:

// 大數乘法;大數開根號;比較大數的大小;

#include#include#includeusing namespace std;

const int max=1100;

string s1,s2; // n,m;

int len1,len2; // 記錄開根號後大數的位數;

int sqrta[max],sqrtb[max];

int a[max];

int temp[max],ans[max];

int compare(int a,int b,int len1,int len2)

// 將s開根號,儲存在a中,並且返回開根號後a的位數;

int sqrtnum(int *a,string s)

if(flag==0) break;

else if(flag==1) a[i]--;

}return len;

}int main()

{ memset(sqrta,0,sizeof(sqrta));

memset(sqrtb,0,sizeof(sqrtb));

cin>>s1>>s2;

len1=sqrtnum(sqrta,s1);

len2=sqrtnum(sqrtb,s2);

int len=mul(ans,sqrta,sqrtb,len1,len2);

for(int i=len-1;i>=0;i--)

cout<

歷屆試題 矩陣翻硬幣

問題描述 小明先把硬幣擺成了乙個 n 行 m 列的矩陣。隨後,小明對每乙個硬幣分別進行一次 q 操作。對第x行第y列的硬幣進行 q 操作的定義 將所有第 i x 行,第 j y 列的硬幣進行翻轉。其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。當小明對所有硬幣都進行了一次 q 操作後,他...

歷屆試題 矩陣翻硬幣

問題描述 小明先把硬幣擺成了乙個 n 行 m 列的矩陣。隨後,小明對每乙個硬幣分別進行一次 q 操作。對第x行第y列的硬幣進行 q 操作的定義 將所有第 ix 行,第 jy 列的硬幣進行翻轉。其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。當小明對所有硬幣都進行了一次 q 操作後,他發現...

歷屆試題 翻硬幣

歷屆試題 翻硬幣 時間限制 1.0s 記憶體限制 256.0mb 問題描述 小明正在玩乙個 翻硬幣 的遊戲。桌上放著排成一排的若干硬幣。我們用 表示正面,用 o 表示反面 是小寫字母,不是零 比如,可能情形是 oo oooo 如果同時翻轉左邊的兩個硬幣,則變為 oooo oooo 現在小明的問題是 ...