蓝桥杯-矩阵翻硬币

问题描述
  小明先把硬币摆成了一个 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次方)。
解题思路:因为硬币最后都正面朝上,所以只要统计那些硬币翻了奇数次就行了。
那么怎么求得那些硬币翻了奇数次呢?
假如某个硬币的位置是 a行 b列。
那么是不是存在任意的组合 i*x=a ,j*y=b。就可以翻硬币。
易知,翻硬币的次数  times = (a的约数的个数)*(b的约数的个数)。
易知,奇数乘奇数才能得到奇数。
而且约数个数为奇数的数只能是平方数!
因此最后结果为(n的开方数)*(m的开方数)。
 
---------------------------------------------------------------------------------------------------
 
ps:代码通过率90%
 
代码如下:
 
 1 #include<iostream>
 2 #include<bits/stdc++.h>
 3 #include<string>
 4 #include<string.h>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 
 9 string Multstr(string str1,string str2){   //大数相乘
10 
11     string strResult = "";
12     int len1 = str1.length();
13     int len2 = str2.length();
14     int num[500] = {0};
15     for(int i=0;i<len1;i++){
16         for(int j=0;j<len2;j++){
17             num[len1-1-i+len2-1-j]+=(str1[i]-'0')*(str2[j]-'0');
18         }
19     }
20     for(int i=0;i<len1+len2;i++){
21         num[i+1]+=num[i]/10;
22         num[i]=num[i]%10;
23     }
24     int a=0;
25     for(int i=len1+len2-1;i>=0;i--){
26         if(num[i]!=0){
27             a=i;break;
28         }
29     }
30     for(int i=a;i>=0;i--){
31         strResult += num[i]+'0';
32     }
33     return strResult;
34 }
35 string Big_sqrt(string a){   //大数开方
36     int alen =a.length();
37     string asqrt="";
38     if(alen%2==0){
39         for(int i=0;i<alen/2;i++){
40             asqrt+="0";
41         }
42     }else{
43         for(int i=0;i<alen/2+1;i++){
44             asqrt+="0";
45         }
46     }
47     int now=0;
48     string sum1,sum2;
49     sum1=Multstr(asqrt,asqrt);
50     while( alen%2==0 ? now!=alen/2 : now!=alen/2+1){
51         string tmp1=asqrt;
52         for(int i=0;i<9;i++){
53             tmp1[now]=tmp1[now]+1;
54             sum2=Multstr(tmp1,tmp1);
55             if(sum1==a){
56                 return asqrt;
57             }
58             if(sum1<=a&&sum2>a&&sum2.length()==a.length()){
59                 break;
60             }
61             if(sum1<=a&&sum2.length()>a.length()){
62                 break;
63             }
64             asqrt=tmp1;
65             sum1=sum2;
66         }
67         now++;
68     }
69     return asqrt;
70 }
71 int main(){
72     string a,b;
73     cin>>a>>b;
74     string a1,b1;
75     a1=Big_sqrt(a);
76     b1=Big_sqrt(b);
77     cout<<Multstr(a1,b1)<<endl;
78     return 0;
79 }

 

 
posted @ 2018-03-06 14:31  ISGuXing  阅读(328)  评论(0编辑  收藏  举报