题解:P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布

· · 题解

题目大意

是石头剪刀布多了两种出法,胜负关系正如题目中给的表格,给出两个人的猜拳周期和游戏局数,每一次赢的人得 1 分,输的得 0 分,平局两人都得 0 分,要我们求出最后两个人的总得分。

大体思路

可以看到游戏局数不大于 200,所以我们可以直接模拟得到。

一个思路简易的方法是把所有输赢关系都存到数组 sy 里。

sy[0][0]=0;
sy[0][1]=0;
sy[0][2]=1;
sy[0][3]=1;
sy[0][4]=0;
sy[1][0]=1;
sy[1][1]=0;
sy[1][2]=0;
sy[1][3]=1;
sy[1][4]=0;
sy[2][0]=0;
sy[2][1]=1;
sy[2][2]=0;
sy[2][3]=0;
sy[2][4]=1;
sy[3][0]=0;
sy[3][1]=0;
sy[3][2]=1;
sy[3][3]=0;
sy[3][4]=1;
sy[4][0]=1;
sy[4][1]=1;
sy[4][2]=0;
sy[4][3]=0;
sy[4][4]=0;

我这里和题目中一样,0 表示剪刀,1 表示石头,2 表示布,3 表示蜥蜴人,4 表示斯波克。

然后按照周期模拟两个人所做出的手势,每次询问即可。

Code

#include<bits/stdc++.h>
using namespace std;
int sy[5][5];
int a[205],b[205];
int main(){
    int n,na,nb;
    cin>>n>>na>>nb;
    sy[0][0]=0;
    sy[0][1]=0;
    sy[0][2]=1;
    sy[0][3]=1;
    sy[0][4]=0;
    sy[1][0]=1;
    sy[1][1]=0;
    sy[1][2]=0;
    sy[1][3]=1;
    sy[1][4]=0;
    sy[2][0]=0;
    sy[2][1]=1;
    sy[2][2]=0;
    sy[2][3]=0;
    sy[2][4]=1;
    sy[3][0]=0;
    sy[3][1]=0;
    sy[3][2]=1;
    sy[3][3]=0;
    sy[3][4]=1;
    sy[4][0]=1;
    sy[4][1]=1;
    sy[4][2]=0;
    sy[4][3]=0;
    sy[4][4]=0;//我们先与处理出所有可能对局的输赢情况 
    for(int i=0;i<na;i++){
        cin>>a[i];
    }
    for(int i=0;i<nb;i++){
        cin>>b[i];
    }
    int suma=0,sumb=0;
    for(int i=0;i<n;i++){
        suma+=sy[a[i%na]][b[i%nb]];
        sumb+=sy[b[i%nb]][a[i%na]];//按照周期模拟
    }
    cout<<suma<<" "<<sumb;//输出答案
    return 0;
}