现在的位置: 首页 > 综合 > 正文

poj3735

2018年04月26日 ⁄ 综合 ⁄ 共 1280字 ⁄ 字号 评论关闭

【题意】

有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.
【上篇】
【下篇】

抱歉!评论已关闭.