【题意】
有n只兔子,有如下三种操作
g i:给兔子i一颗花生
e i:让兔子i把花生吃完
s i j:将兔子i和兔子j的花生交换
初始兔子都没有花生,求m轮交换后各个兔子有多少花生
【输入】
多组数据,数据以一行三个0结束
每组数据第一行n、m、k
接下来k行每行一个操作
【输出】
对于每组数据,输出n个数表示m轮操作后兔子的数量
这个m很大,还要输出所有兔子的情况,很容易联想到矩阵
怎么搞转移矩阵呢,发现只有加1比较难为人
这个我们加一只虚拟兔子0就好了
初始矩阵为单位矩阵
给兔子i一颗花生就是将(i,0)加一
让兔子吃完花生就是将兔子所对的一行清空
交换就是将兔子对应的两行交换
然后快速幂搞一搞就好了
program poj3735;
type
arr=array [0..100] of int64;
square=array [0..100] of arr;
var
n,m,k,i,j:longint;
ans,root:square;
order:char;
procedure swap (var a,b:arr);
var
i:arr;
begin
i:=a;
a:=b;
b:=i;
end;
function matrixmul (a,b:square):square;
var
i,j,k:longint;
ans:square;
begin
fillchar(ans,sizeof(ans),0);
for i:=0 to n do
for k:=0 to n do
if a[i,k]<>0 then
for j:=0 to n do
ans[i,j]:=ans[i,j]+a[i,k]*b[k,j];
exit(ans);
end;
function power (m:longint):square;
var
ans,now:square;
i:longint;
begin
fillchar(ans,sizeof(ans),0);
if m=0 then exit(ans);
for i:=0 to n do
ans[i,i]:=1;
now:=root;
while m<>0 do
begin
if m and 1 = 1 then ans:=matrixmul(ans,now);
m:=m div 2;
now:=matrixmul(now,now);
end;
exit(ans);
end;
begin
repeat
readln(n,m,k);
if (n=0)and(m=0)and(k=0) then break;
fillchar(root,sizeof(root),0);
for i:=0 to n do
root[i,i]:=1;
while k>0 do
begin
dec(k);
read(order);
case order of
'g':begin
read(i);
inc(root[i,0]);
end;
'e':begin
read(i);
root[i]:=root[0];
root[i,0]:=0;
end;
's':begin
read(i,j);
swap(root[i],root[j]);
end;
end;
readln;
end;
ans:=power(m);
for i:=1 to n do
write(ans[i,0],' ');
writeln;
until false;
end.