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 |
题意:有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;
}