生活大爆炸版 石头剪刀布
描述
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一 样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。 升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。 蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以“石头-布-石头-剪刀-蜥蜴人-斯波克”长度 为 6 的周期出拳,那么他的出拳序列就是“石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-……”,而如果小 B 以“剪刀-石头-布-斯波克-蜥蜴人”长度为 5 的周 期出拳,那么他出拳的序列就是“剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-……”
已知小 A 和小 B 一共进行 N 次猜拳。每一次赢的人得 1 分,输的得 0 分;平局两人都 得 0 分。现请你统计 N 次猜拳结束之后两人的得分。
格式
输入格式
第一行包含三个整数:N,NA,NB,分别表示共进行 N 次猜拳、小 A 出拳的周期长度, 小 B 出拳的周期长度。数与数之间以一个空格分隔。
第二行包含 NA 个整数,表示小 A 出拳的规律,第三行包含 NB 个整数,表示小 B 出拳 的规律。其中,0 表示“剪刀”,1 表示“石头”,2 表示“布”,3 表示“蜥蜴人”, 4 表示 “斯波克”。数与数之间以一个空格分隔。
输出格式
输出一行, 包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。
限制
对于 100%的数据,0 < N ≤ 200,0 < NA ≤ 200, 0 < NB ≤ 200。
解题报告
首先,这是一道水题,十多分钟就做出来了,还一遍就过了。。但其实看这个代码,还是有很多不足,因为太长了,也许不需要这么复杂的判断。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,na,nb,scoa,scob; 5 int a[205],b[205]; 6 void winit(int x,int y) 7 { 8 if (x==y) return ; 9 if (x==0) 10 { 11 if (y==2||y==3) scoa++; 12 else scob++; 13 return ; 14 } 15 if (x==1) 16 { 17 if (y==0||y==3) scoa++; 18 else scob++; 19 return ; 20 } 21 if (x==2) 22 { 23 if (y==1||y==4) scoa++; 24 else scob++; 25 return ; 26 } 27 if (x==3) 28 { 29 if (y==2||y==4) scoa++; 30 else scob++; 31 return ; 32 } 33 if (x==4) 34 { 35 if (y==0||y==1) scoa++; 36 else scob++; 37 return ; 38 } 39 } 40 int main() 41 { 42 freopen("rps.in","r",stdin); 43 freopen("rps.out","w",stdout); 44 cin>>n>>na>>nb; 45 for (int i=1;i<=na;i++) 46 scanf("%d",&a[i]); 47 for (int i=1;i<=nb;i++) 48 scanf("%d",&b[i]); 49 int ia=1,ib=1,k=0; 50 while (k<n) 51 { 52 k++; 53 if (ia>na) ia=1; 54 if (ib>nb) ib=1; 55 winit(a[ia],b[ib]); 56 ia++;ib++; 57 } 58 printf("%d %d",scoa,scob); 59 return 0; 60 }
然后上vijos上看题解,发现了一位现在已经退出信竞的同学的题解,用了一个增量数组,值得借鉴。
1 include<stdio.h> 2 int a[205],b[205]; 3 const int f[5][5]={{0,0,1,1,0}, 4 {1,0,0,1,0}, 5 {0,1,0,0,1}, 6 {0,0,1,0,1}, 7 {1,1,0,0,0}}; 8 int main() 9 { 10 int n,y,z,i,y1=0,z1=0,a1=0,b1=0; 11 scanf("%d%d%d",&n,&y,&z); 12 for (i=1;i<=y;i++) scanf("%d",&a[i]); 13 for (i=1;i<=z;i++) scanf("%d",&b[i]); 14 for (i=1;i<=n;i++) 15 { 16 y1=i%y; 17 if (i%y==0) y1=y; 18 z1=i%z; 19 if (i%z==0) z1=z; 20 a1+=f[a[y1]][b[z1]]; 21 b1+=f[b[z1]][a[y1]]; 22 } 23 printf("%d %d",a1,b1); 24 return 0; 25 }