您的位置:首页 > 其它

历届试题 矩阵翻硬币

2015-01-30 16:43 141 查看
历届试题 矩阵翻硬币

时间限制: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次方)。

下面是我的代码:

#include <stdio.h>
#include <string.h>

void multiply(char a[],char b[],char result[])
{
	int lenOfA = strlen(a) ;
	int lenOfB = strlen(b) ;
	int temp[1100] ; 
	memset(temp,0,sizeof(int)*1100) ;
	int k = 0 , j = 0;
	for(int i = lenOfA-1 ; i >= 0 ; --i)
	{
		k = j ;
		++j;
		for(int m = lenOfB-1 ; m >= 0 ; --m)
		{
			temp[k++] += (a[i]-'0')*(b[m]-'0') ;
		}
	}
	int i = 0 ;
	while(i <= lenOfA+lenOfB)
	{
		if(temp[i]>9)
		{
			temp[i+1] += temp[i]/10;
			temp[i]=temp[i]%10 ;
		}
		++i ;
	}
	while(temp[i] > 9)        
	{
		temp[i+1] += temp[i]/10;
		temp[i]=temp[i]%10 ;
		i++;
	}
	while(temp[i]==0)
	{
		i-- ;
	}
	k = 0;
	for(int j = i ; j >= 0 ; --j)
	{
		result[k++] = temp[j]+'0' ; 
	}
	result[k]='\0' ;
}

int compare(char str1[],char str2[])
{
	int len1 = strlen(str1);
	int len2 = strlen(str2);
	if(len1>len2)
	{
		return 1;
	}
	else if(len1<len2)
	{
		return -1 ;
	}
	else
	{
		return strcmp(str1,str2) ;
	}
	
}
void sqrtLarge(char num[],char str[])
{
	int lenOfNum = strlen(num),len ;
	char result[1100];
	if( lenOfNum%2 == 0 )
	{
		len = lenOfNum/2 ;
	}
	else
	{
		len = (lenOfNum+1)/2 ;
	}
	for(int i = 0 ;i < len ; ++i)
	{
		str[i]='0' ;
	}
	str[len]='\0' ;
	for(int i = 0 ; i < len ; ++i)
	{
		while(true)
		{
			str[i] += 1 ;
			multiply(str,str,result);
			if(compare(result,num)>0)
			{
				str[i]=str[i]-1;
				break;
			}
			else if(compare(result,num)==0)
			{
				goto loop ;
			}
		}
	}
	loop:
		return ;
}

int main()
{
	char m[1010] , n[1010] ;
	//freopen("C:\\Users\\Lionel\\Desktop\\in.txt","r",stdin);
	while(scanf("%s%s",m,n) != EOF)
	{
		char ansm[1100],ansn[1100],result[1100];
		sqrtLarge(m,ansm) ;
		sqrtLarge(n,ansn) ;
		multiply(ansm,ansn,result);
		printf("%s\n",result) ;
	}
	return 0 ;
}


详细步骤分析请看:矩阵翻硬币 蓝桥杯

这篇博客已经说绝了。我没什么可说的了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: