歷屆試題 矩陣翻硬幣
阿新 • • 發佈:2019-01-30
歷屆試題 矩陣翻硬幣
時間限制:1.0s 記憶體限制:256.0MB
問題描述
小明先把硬幣擺成了一個 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次方)。
以後已解決 百度一下 sizeof 百度百科就知道了。。
隨後,小明對每一個硬幣分別進行一次 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次方)。
推規律+大數
http://blog.csdn.net/snailset/article/details/26752435這篇文章大家可以看看怎麼推得,寫的很好
下面附上只有90分的程式碼。。有一組資料超時了,其他的都是對的,,我也不想改了,畢竟搞了一天了,然後發現有些基礎的東西都沒搞懂,比如說memset,
對於傳參過來的陣列char a[],sizeof(a)為4 對於在函式體內部定義的陣列char c[1101] sizeof(c)是1101,你說奇不奇怪,就因為這個問題找了好久,導致陣列沒有被初始化完,然後後面的大數相乘得結果也是錯的。。會不會因為陣列在傳參的時候只是把地址傳過來了,並沒有把記憶體大小傳過來,,
#include <iostream> #include <cstring> #include <cmath> using namespace std; void muity(char aa[],char b[],char cc[])//大數相乘 { int i,j,k; int c[1101]; int lena=strlen(aa); int lenb=strlen(b); memset(c,0,sizeof(c)); //cout<<aa<<" "<<b<<endl; for(i=lenb-1,k=0;i>=0;i--) { for(j=lena-1,k=lenb-i-1;j>=0;j--,k++) { c[k] +=(b[i]-'0')*(aa[j]-'0'); c[k+1] += (c[k]/10); c[k] %= 10; } } if(c[k]) ++k; for(i=k-1,j=0;i>=0;i--) { cc[j++] = c[i] + '0'; } cc[j] = '\0'; //cout<<cc<<endl; } void get_bit(char s[],int len,char aa[]) { int i,j; char c[1101]; //cout<<s<<" "<<len<<endl; //cout<<sizeof(aa)<<endl<<sizeof(c)<<endl;為什麼這裡的兩個陣列的位元組大小不同 。。。 memset(aa,'0',len*sizeof(char)); memset(c,'0',sizeof(c)); aa[len] = '\0'; //cout<<len<<endl; for(i=0;i<len;i++) { for(j=9;j>=(i?0:1);j--) { aa[i] = j+'0'; //cout<<aa<<endl; muity(aa,aa,c); //cout<<c<<endl; if(strlen(c) <= strlen(s)) { if(strlen(c) == strlen(s) ) { if(strcmp(c,s) > 0) continue; } } else continue; break; } } //cout<<aa<<endl; } void get_sqrt(char n[],char m[],char res[]) { int lenn,lenm; char a[1101],b[1101]; lenn = strlen(n); lenm = strlen(m); //cout<<lenn<<" "<<lenm<<endl; if(lenn%2) lenn = lenn/2+1; else lenn = lenn/2; if(lenm%2) lenm = lenm/2+1; else lenm = lenm/2; get_bit(n,lenn,a); get_bit(m,lenm,b); muity(a,b,res); } int main() { int i,j,k,l; char n[1101],m[1101],res[1101]; while(~scanf("%s%s",n,m)) { if(strlen(n) > strlen(m)) get_sqrt(n,m,res); else get_sqrt(m,n,res); // muity(n,m,res); printf("%s\n",res); } return 0; }
以後已解決 百度一下 sizeof 百度百科就知道了。。