试题 算法训练 生活大爆炸版石头剪刀布

资源限制
时间限制:1.0s 内存限制:128.0MB


问题描述
  石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
  斯波克:《星际迷航》主角之一。
  蜥蜴人:《星际迷航》中的反面角色。
  这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果
试题 算法训练 生活大爆炸版石头剪刀布_第1张图片


现在,小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的得分。
样例输入
10 5 6
0 1 2 3 4
0 3 4 2 1 0
样例输出
6 2


样例输入
9 5 5
0 1 2 3 4
1 0 3 2 4
样例输出
4 4


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


思路解析:

试题 算法训练 生活大爆炸版石头剪刀布_第2张图片

  • 先把A得分和A失分(即B得分)的情况写出来
  • 找出相同点和不同点
  • 找出相同点中的不同点

举例说明:当A[X]-B[Y]=-3的时候,在A得分的情况下:A[X]=0,即当同时满足A[X]-B[Y]=-3,且A[X]=0,这两个条件时,即A得分。

源程序:

#include<iostream>
using namespace std;
#define maxsize 10000
int a[maxsize];
int b[maxsize];
void init(int NA, int NB)//输入数据
{
     
	for (int i = 0; i < NA; i++)
		cin >> a[i];
	for (int i = 0; i < NB; i++)
		cin >> b[i];
}
void grade(int N,int NA,int NB)//输出两人的分数
{
     
	int sum1=0, sum2=0;
	int x, y, item;
	for (int i = 0; i < N; i++)//此处是猜拳N次
	{
     
		x = i%NA;//利用求余即可获得对应的编号
		y = i%NB;
		item = a[x] - b[y];//两者相见,根据上图所示,把A得分的条件和失分的条件写清楚即可。
		if (item > 0)
		{
     
			if (item == 2 || (item == 1 && a[x] == 4) || (item == 3 && a[x] == 3))//此处为B得分的情况,
				sum2++;
			else
				sum1++;
		}
		if (item < 0)
		{
     
			if (item == -2 || (item == -3 && a[x] == 0) || (item == -1 && a[x]  == 3))//A得分
				sum1++;
			else
				sum2++;
		}
	}
	cout << sum1 << " " << sum2;
}
int main()
{
     
	int N, NA, NB;
	cin >> N >> NA >> NB;
	init(NA, NB);
	grade(N, NA, NB);
}

评测记录:

在这里插入图片描述

补充:

本题N指的是猜拳的次数,我开始的时候,以为N是猜拳的轮数,然后感觉和之前学习队列时候的题目差不多,要用到循环队列。后来发现测试的时候不对,又重新读了一遍题目,发现N是次数,好家伙这样更简单了许多。然后我就想着这样也没意思,我要做出比较真实的猜拳,于是我把题目改了一下:

  • N为进行的轮数
  • 两人出拳没有规律,即加入时间种子,根据系统时间产生随机数

最近我会把这道修改后的题目发表出来,感兴趣的可以看一下。

你可能感兴趣的:(蓝桥杯,c#)