这题是矩阵运算的经典题目。
可以将peanut初始化为{{0},{0},{0},{1}},然后对peanut矩阵进行变换(行变换,可以对单位矩阵操作,然后放在左边乘以peanut。列变换则放在右边)。还有矩阵的运算符合结合率,不符合交换率。
进行矩阵的N次方运算的时候,我一直没用二进制的思想,一直在模拟递归的过程,结果不断超时,感觉复杂度跟二进制的思想差不多的,奇怪了。后来用了二进制的思想才过了。二进制的思想就是不断进行的平方的运算,如果遇到1就累加上去。
可以将peanut初始化为{{0},{0},{0},{1}},然后对peanut矩阵进行变换(行变换,可以对单位矩阵操作,然后放在左边乘以peanut。列变换则放在右边)。还有矩阵的运算符合结合率,不符合交换率。
进行矩阵的N次方运算的时候,我一直没用二进制的思想,一直在模拟递归的过程,结果不断超时,感觉复杂度跟二进制的思想差不多的,奇怪了。后来用了二进制的思想才过了。二进制的思想就是不断进行的平方的运算,如果遇到1就累加上去。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct MATRIX
{
long long m[110][110];
};
MATRIX mul(MATRIX num1,int n1,int m1,MATRIX num2,int n2,int m2)//m1 = n2
{
MATRIX res;
memset(&res, 0, sizeof(res));
int i,j,k;
{
for(i = 0; i <= n1; i++)
{
for(k = 0; k <= m1; k++)
{
if(num1.m[i][k] != 0)
{
for(j = 0; j <= m2; j++)
{
res.m[i][j] += num1.m[i][k] * num2.m[k][j];
}
}
}
}
}
return res;
}
MATRIX POW(MATRIX num1,int k,int n)
{
/* int cnt = 0;
int sta[50];
cnt = -1;
while(k)
{
if((k & 1) == 1)
{
sta[++cnt] = 1;
}
else
{
sta[++cnt] = 0;
}
k = (k >> 1);
}
MATRIX res;
cnt--;
MATRIX first;
memcpy(&first,&num1,sizeof(first));
while(cnt != -1)
{
if(sta[cnt] == 0)
{
num1 = mul(num1,n,n,num1,n,n);
}
else
{
num1 = mul(num1,n,n,num1,n,n);
num1 = mul(first,n,n,num1,n,n);
}
cnt--;
}
*///模拟递归
MATRIX res;
memcpy(&res,&num1,sizeof(num1));
memset(&res,0,sizeof(res));
int i;
for(i = 0; i <= n; i++)
{
res.m[i][i] = 1;
}
while(k)
{
if(k & 1)
{
res = mul(res,n,n,num1,n,n);
}
num1 = mul(num1,n,n,num1,n,n);
k >>= 1;
}//二进制思想
return res;
}
int main()
{
int n,k,m;
while(scanf("%d %d %d",&n,&k,&m) != EOF)
{
if(n == 0 && k == 0 && m == 0)
{
break;
}
int i;
char str[2];
MATRIX cat;
memset(&cat, 0, sizeof(cat));
cat.m[n][0] = 1;
MATRIX one;
memset(&one, 0, sizeof(one));
for(i = 0; i <= n; i++)
{
one.m[i][i] = 1;
}
int j;
for(j = 0; j < m; j++)
{
scanf("%s",str);
int from,to;
if(strcmp(str,"g") == 0)
{
scanf("%d", &from);
one.m[from - 1][n]++;
}
else if(strcmp(str,"e") == 0)
{
scanf("%d",&from);
for(i = 0;i<= n; i++)
{
one.m[from - 1] [i] = 0;
}
}
else if(strcmp(str,"s") == 0)
{
scanf("%d %d", &from, &to);
from--;
to--;
int temp[110];
for(i = 0 ;i <= n; i++)
{
temp[i] = one.m[from][i];
one.m[from][i] = one.m[to][i];
one.m[to][i] = temp[i];
}
}
}
one = POW(one,k,n);
cat = mul(one,n,n,cat,n,1);
for(i = 0; i < n; i++)
{
printf("%lld%c",cat.m[i][0],i==n-1? '\n':' ');
}
}
}