现将上述一组操作做m次后,问每只猫咪有多少颗花生。
3070题意:求第n个斐波那契数的最后4位。
思路:将每一组操作用矩阵A描述,然后就是矩阵快速幂了。对于样例构造的矩阵见代码后注释。最后一列用来表示操作g,操作s就是交换两行,e则是将此行清0。实际上最后所得应该是A^n再乘以一个(n+1)*1的前n个数为0,最后一个数为1的矩阵(全0表示初始时各猫咪拥有的花生数量),实际上得到的就是最后一列的前n个数。
3070思路:采用矩阵相乘的求法(题意中给出的求法),中间计算的时候mod10000即可。
#include <cstdio> #include <cstring> #define N 105 using namespace std; int n,m,q; struct matrix{ long long s[N][N]; }jz,b; void init(){ int i; memset(b.s, 0, sizeof(b.s)); memset(jz.s, 0, sizeof(jz.s)); for(i = 1;i<=n+1;i++){ b.s[i][i] = 1; jz.s[i][i] = 1; } } struct matrix multi(struct matrix x,struct matrix y){ int i,j,k; struct matrix res; memset(res.s, 0, sizeof(res.s)); for(i = 1;i<=n+1;i++) for(j = 1;j<=n+1;j++) if(x.s[i][j]) for(k = 1;k<=n+1;k++) res.s[i][k] += x.s[i][j]*y.s[j][k]; return res; } void solve(int d){ while(d){ if(d&1) jz = multi(jz,b); b = multi(b, b); d>>=1; } } int main(){ while(scanf("%d %d %d",&n,&m,&q) && (n+m+q)){ int i,j,k; char ch; init(); getchar(); while(q--){ ch = getchar(); if(ch == 'g'){ scanf("%d\n",&j); b.s[j][n+1] += 1; }else if(ch == 's'){ scanf("%d %d\n",&j,&k); for(i = 1;i<=n+1;i++){ long long tmp = b.s[j][i]; b.s[j][i] = b.s[k][i]; b.s[k][i] = tmp; } }else{ scanf("%d\n",&j); memset(b.s[j], 0, sizeof(long long )*(n+2)); } } solve(m); for(i = 1;i<=n;i++) printf("%lld ",jz.s[i][n+1]); printf("\n"); } return 0; } /* 0 1 0 2 0 0 0 0 0 0 1 1 0 0 0 1 */
3070:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <cstdlib> using namespace std; #define clc(s,t) memset(s,t,sizeof(s)) #define INF 0x3fffffff struct matrix{ int s[2][2]; }b,res; int n; struct matrix multi(struct matrix a,struct matrix b){ struct matrix tmp; int i,j,k; clc(tmp.s, 0); for(i = 0;i<2;i++) for(j = 0;j<2;j++) for(k = 0;k<2;k++){ tmp.s[i][j] += a.s[i][k]*b.s[k][j]; tmp.s[i][j] %= 10000; } return tmp; } void solve(int d){ while(d){ if(d&1) res = multi(res,b); b = multi(b,b); d >>= 1; } } int main(){ while(scanf("%d",&n) && n!=-1){ b.s[0][0] = b.s[0][1] = b.s[1][0] = 1; b.s[1][1] = 0; res.s[0][0] = res.s[1][1] = 1; res.s[0][1] = res.s[1][0] = 0; if(!n){ printf("0\n"); continue; } solve(n); printf("%d\n",res.s[0][1]); } }