1. 程式人生 > >歷屆試題 矩陣翻硬幣

歷屆試題 矩陣翻硬幣

 歷屆試題 矩陣翻硬幣   時間限制: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次方)。

推規律+大數

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  百度百科就知道了。。