[构造] Codeforces Gym 100553 NEERC 14 E. Epic Win!

来源:互联网 发布:如何破解php源码 编辑:程序博客网 时间:2024/05/08 02:48

一道神奇的题 题目大意给你一个剪刀石头布自动机 然后让你构造一个剪刀石头布自动机克制他
这个我们先构造出一个完全针对他的自动机W 无用的边我们先当他undefined
然后我们开始枚举起点一起跑 用双方所在节点(x,y)表示状态
当前状态的转移遍不存在时 我们就把这条边连向W的一个副本的对应节点
如果成环了 那么一定是在一个W的副本里成环 这个环是一直赢的 因为只有W副本之间的转移边可能会输

ps.似乎有一个乱搞做法 没仔细看

#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;#define read(x) scanf("%d",&(x))const int N=50005;int n;int a[N][4],b[N][4],c[N][4];int tot;inline void pb(){  for (int i=1;i<=n;i++){    c[tot*n+i][0]=b[i][0];    for (int j=1;j<=3;j++)      if (b[i][j])    c[tot*n+i][j]=b[i][j]+tot*n;  }  ++tot;}int vst[N][105];int clk;int main(){  char _c;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(n);  for (int i=1;i<=n;i++){    do _c=getchar(); while (!(_c>='A' && _c<='Z'));    a[i][0]=_c=='R'?1:(_c=='P'?2:3);    read(a[i][1]); read(a[i][2]); read(a[i][3]);  }  for (int i=1;i<=n;i++){    b[i][0]=a[i][0]%3+1;    b[i][1]=b[i][2]=b[i][3]=0;    b[i][a[i][0]]=a[i][b[i][0]];  }  pb();  for (int i=2;i<=n;i++){    ++clk;    int x=1,y=i;    while (1){      if (vst[x][y]==clk) break;      vst[x][y]=clk;      if (!c[x][a[y][0]]){    pb();    c[x][a[y][0]]=n*(tot-1)+a[y][c[x][0]];    break;      }      int t=x;      x=c[x][a[y][0]];      y=a[y][c[t][0]];    }  }  printf("%d\n",n*tot);  for (int i=1;i<=n*tot;i++){    putchar(c[i][0]==1?'R':(c[i][0]==2?'P':'S'));    for (int j=1;j<=3;j++)      printf(" %d",c[i][j]==0?1:c[i][j]);    printf("\n");  }  return 0;}