Training little cats
Description Facer's pet cat just gave birth to a brood of little cats. Having considered the health of those lovely cats, Facer decides to make the cats to do some exercises. Facer has well designed a set of moves for his cats. He is now asking you to supervise the cats to do his exercises. Facer's great exercise for cats contains three different moves: Input The input file consists of multiple test cases, ending with three zeroes "0 0 0". For each test case, three integers n, m and k are given firstly, where n is the number of cats and k is the length of the move sequence. The following k lines describe the sequence. Output For each test case, output n numbers in a single line, representing the numbers of peanuts the cats have. Sample Input 3 1 6 g 1 g 2 g 2 s 1 2 g 3 e 2 0 0 0 Sample Output 2 0 1 Source
PKU Campus 2009 (POJ Monthly Contest – 2009.05.17), Facer
|
题意:有n只猫,和k个操作,每次可以给一只猫一个花生,或者让一只猫吃掉手上的所有花生,或者交换两只猫的花生,重复着k个操作m次
分析:本来是很简单的模拟题,不过m太大了,很容易联想到矩阵连乘。。。
然后就是如何转换的问题了,拿一颗花生,其实就是平移。。。。吃掉花生就把对应的行赋值0,交换的话,也就是交换两行
PS:我是不会矩阵的,看了别人的题解才知道平移,记下来了,看来高中落下的一大个坑啊
代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int mm=111; __int64 a[mm][mm],b[mm][mm],c[mm][mm]; int i,j,e,n,m,k; char op[9]; void Multi(__int64 a[mm][mm],__int64 b[mm][mm]) { memset(c,0,sizeof(c)); int i,j,k; for(i=1;i<=n+1;++i) for(k=1;k<=n+1;++k) if(a[i][k])for(j=1;j<=n+1;++j) if(b[k][j])c[i][j]+=a[i][k]*b[k][j]; for(i=1;i<=n+1;++i) for(j=1;j<=n+1;++j) a[i][j]=c[i][j]; } int main() { while(scanf("%d%d%d",&n,&m,&k),n+m+k) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(i=1;i<=n+1;++i)a[i][i]=b[i][i]=1; while(k--) { scanf("%s%d",op,&i); if(op[0]=='g')++a[i][n+1]; if(op[0]=='e') for(j=0;j<=n+1;++j)a[i][j]=0; if(op[0]=='s') { scanf("%d",&j); for(e=1;e<=n+1;++e) swap(a[i][e],a[j][e]); } } while(m) { if(m&1)Multi(b,a); Multi(a,a); m>>=1; } for(i=1;i<=n;++i) printf("%I64d%c",b[i][n+1],i<n?' ':'\n'); } return 0; }