Noip2014 提高组 day1 T1· 生活大爆炸版石头剪刀布

                                               生活大爆炸版 石头剪刀布

描述

石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一 样,则不分胜负。在《生活大爆炸》第二季第 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 的得分。

样例1

样例输入1[复制]

 
10 5 6
0 1 2 3 4
0 3 4 2 1 0

样例输出1[复制]

 
6 2

样例2

样例输入2[复制]

 
9 5 5
0 1 2 3 4
1 0 3 2 4

样例输出2[复制]

 
4 4

限制

对于 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 }
原文地址:https://www.cnblogs.com/lx0319/p/5683362.html