ASC1 E Nice Patterns Strike Back

题意:给你N×(1-5)的格子,每一个格子有两张颜色,其中2x2个格子内的颜色不能都相同。

解题思路:状态压缩+ 矩阵快速幂 +大数。

解题代码:

  1 // File Name: e.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年03月21日 星期六 19时58分58秒
  4
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #define LL long long
 25
 26 using namespace std;
 27 int M , n ;
 28 struct Matrix
 29 {
 30    int mat[40][40];
 31    void clear()
 32    {
 33       memset(mat,0,sizeof(mat));
 34    }
 35    void output()
 36    {
 37        for(int i = 0 ;i < n;i ++)
 38        {
 39          for(int j = 0 ;j < n;j ++)
 40          {
 41            printf("%d ",mat[i][j]);
 42          }
 43          printf("\n");
 44        }
 45    }
 46    Matrix operator *(const Matrix &b) const
 47    {
 48       Matrix ret;
 49       ret.clear();
 50       for(int i =  0 ;i < n;i ++)
 51           for(int j = 0 ;j < n;j ++)
 52           {
 53               for(int s = 0 ; s < n; s ++)
 54               {
 55                 ret.mat[i][j] = (ret.mat[i][j] + mat[i][s] *b.mat[s][j] % M) % M;
 56               }
 57           }
 58       return ret;
 59    }
 60 }a;
 61 char str[1000];
 62 int num[1000];
 63 int len ;
 64 int t;
 65 void judge(int x, int y)
 66 {
 67   //printf("%d %d***\n",x,y);
 68    int tx = x;
 69    int ty = y;
 70    int ttt = 0 ;
 71    int txa[10];
 72    int tya[10];
 73    memset(txa,0,sizeof(txa));
 74    memset(tya,0,sizeof(tya));
 75    while(tx)
 76    {
 77       txa[ttt] = tx % 2;
 78       tx/= 2;
 79       ttt++;
 80    }
 81    ttt =0 ;
 82    while(ty)
 83    {
 84       tya[ttt] = ty % 2;
 85       ty /= 2;
 86       ttt++;
 87    }
 88    for(int i = 1;i < t; i ++)
 89        if(tya[i]+tya[i-1]+txa[i] + txa[i-1] == 4 || tya[i] + tya[i-1] + txa[i] + txa[i-1] == 0 )
 90        {
 91            return;
 92        }
 93    a.mat[x][y] = 1;
 94 }
 95 void jian()
 96 {
 97    for(int i= 0 ;i <= len/2;i ++)
 98     {
 99         swap(num[i],num[len-i]);
100     }
101    for(int i = 0 ;i <= len ;i ++)
102    {
103         if(num[i] == 0 )
104         {
105            num[i] = 9 ;
106         }else{
107            num[i]-- ;
108            break;
109         }
110    }
111      /*for(int i = len ;i >= 0 ;i --)
112          printf("%d",num[i]);
113      printf("\n");*/
114    if(num[len] == 0 )
115        len --;
116    /*
117      for(int i = len ;i >= 0 ;i --)
118          printf("%d",num[i]);
119      printf("\n");*/
120 }
121 void chu()
122 {
123      int tmp = 0 ;
124      for(int i = len ;i >= 0 ;i --)
125      {
126          int k = (tmp * 10 + num[i]);
127          num[i] = k/2;
128          tmp = k % 2;
129      }
130      if(num[len] == 0 )
131          len --;
132      /*
133      for(int i = len ;i >= 0 ;i --)
134          printf("%d",num[i]);
135      printf("\n");*/
136 }
137 Matrix Pow(Matrix a)
138 {
139    Matrix ret;
140    ret.clear();
141    for(int i= 0 ;i < n;i ++)
142       ret.mat[i][i] = 1;
143    Matrix tmp = a;
144    while(len != -1)
145    {
146       // printf("%d ***\n",len);
147         if(num[0] % 2 == 1)
148         {
149             ret = ret * tmp ;
150             //ret.output();
151         }
152         tmp = tmp*tmp ;
153         chu();
154    }
155    return ret;
156 }
157 int main(){
158     freopen("nice.in","r",stdin);
159     freopen("nice.out","w",stdout);
160
161     scanf("%s %d %d",str,&t,&M);
162     len = strlen(str);
163     for(int i=  0 ;i < len ;i ++)
164     {
165       num[i] = str[i] - ‘0‘;
166     }
167     len --;
168     n = (1 << t);
169     for(int i = 0 ;i <n ;i ++)
170     {
171       for(int j = 0 ;j < n;j ++)
172       {
173          judge(i,j);
174       }
175     }
176    // a.output();
177     jian();
178     a = Pow(a);
179     //a.output();
180     int sum = 0 ;
181     for(int i = 0 ;i < n;i ++)
182         for(int j = 0 ;j < n;j ++)
183     {
184         sum = (sum + a.mat[i][j]) % M;
185     }
186     printf("%d\n",sum);
187
188 return 0;
189 }

时间: 2024-10-15 09:48:41

ASC1 E Nice Patterns Strike Back的相关文章

ZOJ2317-Nice Patterns Strike Back:矩阵快速幂,高精度

Nice Patterns Strike Back Time Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) Problem Description You might have noticed that there is the new fashion among rich people to have their yards tiled with black and white tile

【ZOJ】Nice Patterns Strike Back(矩阵快速乘法)

dp[[i][j] = sum(dp[i - 1][k]) (k -> j) 状态方程,因为N很大而M很小,所以第一时间可以想到矩阵优化 可能之前没做过类似的题被卡的很厉害. 另外用C++写大数真心麻烦.. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 45; const int maxd = 30005; char n[ma

ZOJ 2317 Nice Patterns Strike Back

题意 在一个N*M的矩阵中给每个格子染上黑白色,要求任意一个2*2的矩阵颜色不能一样,N<=10^100,m<=5. 解法 首先看这个题,若n和m很小,则我们可以直接用状态压缩乱搞,但是N太大了,显然只能是快速幂(看到这个题的第一感觉),然后就是构造矩阵,在矩阵快速幂,不说了,网上说的比我好的太多了.这个题我并不想写这个博客的,但是由于它是我第一个java程序(虽然以前写过一个,不过那个是a+b问题),所以纪念一下 import java.util.*; import java.math.*;

zoj 2317 Nice Patterns Strike Back(矩阵乘法)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1317 给出一个n*m的矩阵(n <= 10^100, m <= 5),对于2*2的子方格若全是黑色或全是白色的是非法的,用黑白两色去染n*m的方格,问共有多少种合法的染色方案. 构造出转移矩阵,上一行向下一行的转移矩阵,因为m<=5,每行最多有32个状态,可以进行状态压缩构造出一个32*32的转移矩阵A,A[i][j] = 1表示上一行i状态可以向下一行的j状态转移,

SGU 197 Nice Patterns Strike Back || ZOJ 2317 Nice Patterns Strike Back

题目链接~~> 做题感悟:做了这题感觉学习了不少东西,首先是关于状态压缩推公式学会了. 解题思路: 构造矩阵: B[ i ][ j ] (i , j 为状态,0 <= i ,j  <= (1<<m) - 1 ) , 如果 B[ i ] [ j ]  等于 1 代表状态 i 与状态 j 相互兼容(i , j 可以在相邻两行),如果为 0 代表不可以相邻,还要有一个原始矩阵 A ,(1<<m)-1 行 ,1列的矩阵  ,代表第一行各种状态的方案数,这样 B *  A

快速矩阵幂+DFS构造矩阵+大数 ACdream1214 Nice Patterns Strike Back

传送门:点击打开链接 题意:告诉你矩阵大小是n*m,要求矩阵中不能有2*2的白色子矩阵或者黑色子矩阵,最后种类数模P 思路:如果不是大数,这道题还是非常有意思的..对于专门卡C++的题目也是醉了...因为n太大了,而m最大也只有5,很明显是大数上的快速矩阵幂. 问题是如何构造出矩阵出来,之前做过骨牌的题目,就是利用DFS来构造的,感觉这道题在思路上是一样的,同样也是利用DFS先构造出矩阵 然后直接大数+快速矩阵幂撸一发就行了 #include<map> #include<set>

SGU 197.Nice Patterns Strike Back

时间限制:0.5s 空间限制:6M 题意: 给出长n(n<=10^100)和宽m(m<=5)的地面,铺上黑色和白色的地板,使得没有任意一个2*2大小的地面铺同种颜色的方案数是多少. Solution: 状态压缩,一个数字的对应为01分别代表铺白色和黑色地板,对于每一列有(1<<m)种状态. 我们可以构造一个矩阵,mat[i][j]代表,第一列是状态是i,第二列是j的方案数,显然mat[i][j]不是0就是1,而且很容易判断构造. 然后我们只要对这个矩阵进行快速幂运算,幂为(n-1)

ASC #1

开始套题训练,第一套ASC题目,记住不放过每一题,多独立思考. Problem A ZOJ 2313 Chinese Girls' Amusement 循环节 题意:给定n,为圆环长度,求k <= n/2,从1出发,每次顺时针方向走k步,即1->k+1->2*k+1,直到遇到一个已经走过的点结束,要求最终把所有点访问一遍,最后回到1,使得k尽量大. 代码: Problem B ZOJ 2314 Reactor Cooling 无源汇上下界网络流 题意:经典题,有上下界无源无汇的可行流,对

sgu100~199题解

老东西了..发上来吧.. Sgu题解系列  南开中学邹事成 100:A+B略 101:Domino 给n块多米诺骨牌,每张骨牌两端各有从1到6的一个数字,现在要把这些骨牌排成一列,使相邻的两块骨牌相对的面所写的数字一样. 可以把每一块多米诺骨牌想象成一条边,把面上写的数字抽象成点,比如一块骨牌正面写的1反面写的2就想象成连了一条从1到2的边,那么这就是求一条有重边的欧拉回路了,dfs一下即可. 102:Coprimes给定n求从1到n中与n互质的数的个数. 可以把n质因数分解后直接代入欧拉函数.