题目大意是给你K串命令和N只猫,问执行M次后每只猫的状况
其中
s 命令是交换两只猫的花生
g 命令是一只猫拿一个花生
e 命令是一只猫吃完他的花生
我们很明显用矩阵快速幂来做这道题
只不过会有一些细节问题,就是数组要用long long 来存,因为程序中没有mod来取余,还有就是可能矩阵中会有很多0,所以时间需要优化,毕竟最大100*100的矩阵相乘是O(n*n*n)复杂度。
代码如下
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
struct mmmm
{
LL matrix[105][105];
};
int n,m,k;
mmmm ma_pow(mmmm a,mmmm b)
{
mmmm c;
memset(c.matrix,0,sizeof(c.matrix));
for(int i=0;i<=n;i++){
for(int k=0;k<=n;k++){
if(a.matrix[i][k]!=0){//优化时间
for(int j=0;j<=n;j++){
c.matrix[i][j] += a.matrix[i][k]*b.matrix[k][j];
}
}
}
}
return c;
}
mmmm solve(mmmm a,int m)
{
mmmm c;
memset(c.matrix,0,sizeof(c.matrix));
for(int i=0;i<=n;i++) c.matrix[i][i] = 1;
while(m){
if(m&1) c = ma_pow(c,a);
a = ma_pow(a,a);
m >>= 1;
}
return c;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)&&(n+k+m)){
//printf("%d %d %d\n",n,m,k);
char c;
mmmm aa;
memset(aa.matrix,0,sizeof(aa.matrix));
for(int i=0;i<=n;i++) aa.matrix[i][i] = 1;
for(int i=0,x,y;i<k;i++){
getchar();
scanf("%c",&c);
//printf("%c \n",c);
if(c =='g'){
scanf("%d",&x);
//printf("%d \n",x);
aa.matrix[x-1][n]++;
}else if(c =='e'){
scanf("%d",&x);
//printf("%d\n",x);
memset(aa.matrix[x-1],0,sizeof(aa.matrix[x-1]));
}else if(c =='s'){
scanf("%d%d",&x,&y);
//printf("%d %d\n",x,y);
for(int i=0;i<=n;i++){
swap(aa.matrix[x-1][i],aa.matrix[y-1][i]);
}
}
}
/*
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
printf("%d ",aa.matrix[i][j]);
}
printf("\n");
}
*/
mmmm ans = solve(aa,m);
for(int i=0;i<n;i++){
printf("%lld%c",ans.matrix[i][n],i==n-1?'\n':' ');
}
}
return 0;
}