洛谷题解——P1328 生活大爆炸版石头剪刀布

题目相关

题目链接

洛谷,https://www.luogu.com.cn/problem/P1328

我的 OJ,http://47.110.135.197/problem.php?id=4681

题目描述

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

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

样例 2

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

输出样例

样例 1

6 2

样例 2

4 4

数据规模

对于100%的数据,0 < N ≤ 200, 0 < NA ≤ 200, 0 < NB ​≤ 200 。

题解报告

题意分析

本题属于计算算法的模拟算法,就是用计算机来模拟题目中要求的操作。没有很大难度。

唯一要注意的地方就是胜负表怎么看。我比较笨,我就写出了这样的规则:

1、剪刀 vs 石头。剪刀输,石头赢。

2、剪刀 vs 布。剪刀赢,布输。

3、剪刀 vs 蜥蜴人。剪刀赢,蜥蜴人输。

4、剪刀 vs 斯波克。剪刀输,斯波克赢。

5、石头 vs 布。石头输,布赢。

6、石头 vs 蜥蜴人。石头赢,蜥蜴人输。

7、石头 vs 斯波克。石头输,斯波克赢。

8、布 vs 蜥蜴人。布输,蜥蜴人赢。

9、布 vs 斯波克。布赢,斯波克输。

10、蜥蜴人 vs 斯波克。蜥蜴人赢,斯波克输。

样例数据分析

样例数据 1

根据样例数据 1,一共进行了 10 轮,A 的周期为 5,B 的周期为 6。A 出拳的次序为 0 1 2 3 4,B 出拳的次序为 0 3 4 2 1 0。

由于 A 和 B 的周期不保证一样,我们需要用两个变量分别控制 A 和 B。再使用两个变量表示 A 和 B 的最终得分。这样,我们可以写出如下的 10 轮表格。

轮数 idxA a[idxA] A出拳 idxB b[idxB] B出拳 结果 ansA ansB
初始 0     0       0 0
1 0 0 剪刀 0 0 剪刀 平局 0 0
2 1 1 石头 1 3 蜥蜴人 石头赢 1 0
3 2 2 2 4 斯波克 布赢 2 0
4 3 3 蜥蜴人 3 2 蜥蜴人赢 3 0
5 4 4 斯波克 4 1 石头 斯波克赢 4 0
6 0 0 剪刀 5 0 剪刀 平局 4 0
7 1 1 石头 0 0 剪刀 石头赢 5 0
8 2 2 1 3 蜥蜴人 蜥蜴人赢 5 1
9 3 3 蜥蜴人 2 4 斯波克 蜥蜴人赢 6 1
10 4 4 斯波克 3 2 布赢 6 2

这样,我们可以得到最终比分为 6:2。

数据规模分析

0 < N ≤ 200。非常简单的一个问题。

难点

个人觉得本题的难点有以下几个。

1、如何判断输赢。我比较笨,用了最笨的枚举所有组合情况,实在想不出有什么简单的判断方法。

2、如何控制 A 和 B 的周期。

AC 参考代码

//https://www.luogu.com.cn/problem/P1328
#include <iostream>
using namespace std;

const int MAXN = 2e2+4;
int a[MAXN];
int b[MAXN];

int main() {
    int n, na, nb;
    cin>>n>>na>>nb;
    for (int i=0; i<na; i++) {
        cin>>a[i];
    }
    for (int i=0; i<nb; i++) {
        cin>>b[i];
    }

    int ansa=0;
    int ansb=0;
    int idxa=0;
    int idxb=0;
    for (int i=0; i<n; i++) {
        if (0==a[idxa]) {
            //a 剪刀
            if (0==b[idxb]) {
                //剪刀 vs 剪刀
            } else if (1==b[idxb]) {
                //剪刀 vs 石头
                //剪刀 lose
                ansb++;
            } else if (2==b[idxb]) {
                //剪刀 vs 布
                //剪刀 win
                ansa++;
            } else if (3==b[idxb]) {
                //剪刀 vs 蜥蜴人
                //剪刀 win
                ansa++;
            } else {
                //剪刀 vs 斯波克
                //剪刀 lose
                ansb++;
            }
        } else if (1==a[idxa]) {
            //a 石头
            if (0==b[idxb]) {
                //石头 vs 剪刀
                //石头 win
                ansa++;
            } else if (1==b[idxb]) {
                //石头 vs 石头
            } else if (2==b[idxb]) {
                //石头 vs 布
                //石头 lose
                ansb++;
            } else if (3==b[idxb]) {
                //石头 vs 蜥蜴人
                //石头 win
                ansa++;
            } else {
                //石头 vs 斯波克
                //石头 lose
                ansb++;
            }
        } else if (2==a[idxa]) {
            //a 布
            if (0==b[idxb]) {
                //布 vs 剪刀
                //布 lose
                ansb++;
            } else if (1==b[idxb]) {
                //布 vs 石头
                //布 win
                ansa++;
            } else if (2==b[idxb]) {
                //布 vs 布
            } else if (3==b[idxb]) {
                //布 vs 蜥蜴人
                //布 lose
                ansb++;
            } else {
                //布 vs 斯波克
                //布 win
                ansa++;
            }
        } else if (3==a[idxa]) {
            //a 蜥蜴人
            if (0==b[idxb]) {
                //蜥蜴人 vs 剪刀
                //蜥蜴人 win
                ansb++;
            } else if (1==b[idxb]) {
                //蜥蜴人 vs 石头
                //蜥蜴人 lose
                ansb++;
            } else if (2==b[idxb]) {
                //蜥蜴人 vs 布
                //蜥蜴人 win
                ansa++;
            } else if (3==b[idxb]) {
                //蜥蜴人 vs 蜥蜴人
            } else {
                //蜥蜴人 vs 斯波克
                //蜥蜴人 win
                ansa++;
            }
        } else {
            //a 斯波克
            if (0==b[idxb]) {
                //斯波克 vs 剪刀
                //斯波克 win
                ansa++;
            } else if (1==b[idxb]) {
                //斯波克 vs 石头
                //斯波克 win
                ansa++;
            } else if (2==b[idxb]) {
                //斯波克 vs 布
                //斯波克 lose
                ansb++;
            } else if (3==b[idxb]) {
                //斯波克 vs 蜥蜴人
                //斯波克 lose
                ansb++;
            } else {
                //b 斯波克
            }
        }

        idxa=(idxa+1)%na;
        idxb=(idxb+1)%nb;
    }
    
    cout<<ansa<<" "<<ansb<<"\n";

    return 0;
}

算法复杂度

时间复杂度

O(N)。

空间复杂度

O(N)。

猜你喜欢

转载自blog.csdn.net/justidle/article/details/108331823
今日推荐