根据题意构造变换矩阵即可。有很多构造矩阵的方法。例如,假设原串长度为7,则我构造的矩阵M如下:
1 1 0 0 0 0 0
0 1 1 0 0 0 0
0 0 1 1 0 0 0
0 0 0 1 1 0 0
0 0 0 0 1 1 0
0 0 0 0 0 1 1
1 0 0 0 0 0 1
每次用M右乘原始矩阵就相当于一次变换,用快速幂就可以过了。不过这道题测试数据有点坑爹,我直接用的矩阵模板,超时,手动把矩阵乘法部分改成位运算形式就过了。。。估计之前超时也就超那么一丁点吧,估计加个输入外挂也能过。。。
/* * hdu2276/win.cpp * Created on: 2012-11-3 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; const int MAX_ORDER = 105; typedef bool typec; typedef struct MyMatrix { int order; typec num[MAX_ORDER][MAX_ORDER]; MyMatrix(int ord) { order = ord; } void init() { for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { num[i][j] = 0; } } } } MyMatrix; MyMatrix operator*(MyMatrix ma, MyMatrix mb) { int ord = ma.order; MyMatrix numc(ord); numc.init(); int i, j, k; for (i = 0; i < ord; i++) { for (j = 0; j < ord; j++) { for (k = 0; k < ord; k++) { numc.num[i][j] = numc.num[i][j] xor (ma.num[i][k] and mb.num[k][j]); } } } return numc; } MyMatrix mpow(MyMatrix ma, int x) { int ord = ma.order; MyMatrix numc(ord); numc.init(); for (int i = 0; i < ord; i++) { numc.num[i][i] = 1; } for (; x; x >>= 1) { if (x & 1) { numc = numc * ma; } ma = ma * ma; } return numc; } MyMatrix getTraMatix(int n) { MyMatrix ret(n); ret.init(); for(int j = 0; j < n; j++) { int i = (j - 1 + n) % n; ret.num[j][j] = 1; ret.num[i][j] = 1; } return ret; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif int m; char str[200]; while(scanf("%d", &m) == 1) { getchar(); gets(str); int len = strlen(str); MyMatrix ori(len); ori.init(); for(int i = 0; i < len; i++) { ori.num[0][i] = str[i] - '0'; } MyMatrix tra = mpow(getTraMatix(len), m); MyMatrix result = ori * tra; for(int i = 0; i < len; i++) { printf("%d", result.num[0][i]); } putchar('\n'); } return 0; }