zoukankan      html  css  js  c++  java
  • hdu 2276【Kiki & Little Kiki 2】

    看到有人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 }
  • 相关阅读:
    最简单的UDP程序
    最简单的TCP程序
    一道面试题的分析
    JDK5新特性:可变参数方法
    文件IO流总结
    集合使用的总结
    双列集合Map的嵌套遍历
    集合HashSet的使用
    集合TreeSet的使用
    用LinkedList模拟Stack功能
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2553897.html
Copyright © 2011-2022 走看看