看到有人0ms爽过,我781ms过,心里有点不是滋味儿......
还是说说自己的思路吧:
1、根据题目的意思我们就应该知道是将原来的数据右移(譬如第二位移到第一位),当然了最高位应该被最低位的数补充——这个可以很完美的用矩阵实现,即每列比行大一的位置为0,譬如第一行,第二列的数据为1,但是最后一行是第一列和最后一列为1.
2、移动后的数据与原数据异或得到一次移动后的结果,这个直接可以将主对角线上的数据变为1(经过以上两步构造矩阵后,矩阵相乘时,就把原来的数据与现在的数据相加了),然后所得的数据要模2,为什么这个可以替代异或呢?其实异或本来就是朴素的加法(二进制的),只不过1+1=10,我们取得是最低位罢了,所以可以直接模2.
然后就是代码了。。。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 100+10; 5 const int mod = 2; 6 struct matrix 7 { 8 int mt[maxn][maxn]; 9 }e; 10 11 int n,len; 12 int data[maxn]; 13 int re_ans[maxn]; 14 15 void zero_matrix(matrix& x) 16 { 17 memset(x.mt,0,sizeof(x.mt)); 18 } 19 20 void unit() 21 { 22 zero_matrix(e); 23 for(int i = 0;i < len;i ++) 24 { 25 e.mt[i][i] = 1; 26 } 27 } 28 29 matrix operator*(matrix& x,matrix& y) 30 { 31 matrix ans; 32 for(int i = 0;i < len;i ++) 33 { 34 for(int j = 0;j < len;j ++) 35 { 36 ans.mt[i][j] = 0; 37 for(int k = 0;k < len;k ++) 38 { 39 ans.mt[i][j] += x.mt[i][k] * y.mt[k][j] % mod; 40 } 41 ans.mt[i][j] %= mod; 42 } 43 } 44 45 return ans; 46 } 47 48 matrix operator^(matrix& x,int pow) 49 { 50 matrix ans = e; 51 while(pow) 52 { 53 if(pow & 1) 54 { 55 ans = ans * x; 56 } 57 x = x * x; 58 pow >>= 1; 59 } 60 61 return ans; 62 } 63 64 int main() 65 { 66 while(scanf("%d",&n) == 1) 67 { 68 char input[maxn]; 69 scanf("%s",input); 70 len = strlen(input); 71 for(int i = 0;i < len;i ++) 72 { 73 data[i] = input[i] - '0'; 74 } 75 unit();//构造单位矩阵 76 //构造矩阵 77 matrix tmp; 78 zero_matrix(tmp);//将tmp矩阵刷0 79 for(int i = 0;i < len;i ++) 80 { 81 tmp.mt[i][i] = 1; 82 if(i < len - 1) 83 { 84 tmp.mt[i][i+1] = 1; 85 } 86 else//最后一行比较特殊,是第一列为1 87 { 88 tmp.mt[i][0] = 1; 89 } 90 } 91 tmp = tmp ^ n;//移动n次,矩阵满足结合律 92 for(int i = 0;i < len;i ++)//如果想这里简单一点的话,可以将re_ans直接构造成matrix,我这里是将其构造成1*len矩阵。 93 { 94 re_ans[i] = 0; 95 for(int j = 0;j < len;j ++) 96 { 97 re_ans[i] += data[j] * tmp.mt[j][i] % mod; 98 } 99 re_ans[i] %= mod; 100 } 101 //打印出结果 102 for(int i = 0;i < len;i ++) 103 { 104 printf("%d",re_ans[i]); 105 } 106 printf("\n"); 107 } 108 109 return 0; 110 }