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

原题传送门

Description

甲与乙两人玩一种新的猜拳游戏,规则如下 :

这里我们用 (0) 表示“剪刀”,(1) 表示“石头”,(2) 表示“布”,(3) 表示“蜥蜴人”,(4) 表示“斯波克”。
出拳顺序是固定的,即「剪刀-石头-布-斯波克-蜥蜴人」。
给定进行的猜拳次数,甲乙两人的出拳周期,求甲乙两人的得分(赢者得 (1) 分,输者得 (0) 分,平局均得 (0) 分)。

Solution

非常显然的一道模拟题。

考虑如何简单有效地用较短代码来解决。

根据 Description 中的信息,我们可以把这个游戏的规则示意图简化一下 :

说明 : (可以比照 Description 中的题目原图进行理解)

  • 蓝色的框表示出拳的类型((0) 表示“剪刀”,(1) 表示“石头”,(2) 表示“布”,(3) 表示“蜥蜴人”,(4) 表示“斯波克”),纵列为甲,横行为乙。
  • 绿色的框表示平局的情况,这里单独注明。
  • 黄色的框表示甲对乙的游戏结果,框内表示加的分数(也同时表示输赢情况)

这里有了输赢情况(加分情况),我们可以开一个 win 数组,来记录下所有 AB 的加分情况 :

具体如下 :

int win[10][10]=
{
	
{0,0,1,1,0},
{1,0,0,1,0},
{0,1,0,0,1},
{0,0,1,0,1},
{1,1,0,0,0}

};

再用两个计数器 res1res2 来记录甲乙的得分情况,最后输出。

Code

#include<iostream>
#include<cstdio>
using namespace std;
const int Maxn=210;
inline void read(int &x){
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') x=-x;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<3)+(x<<1)+(ch&15);
		ch=getchar();
	}
	x*=f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int n,n_a,n_b;
int a[Maxn],b[Maxn];
int win[10][10]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};
signed main(){
	int res1=0,res2=0;
	read(n);read(n_a);read(n_b);
	for(int i=0;i<n_a;i++) read(a[i]);
	for(int i=0;i<n_b;i++) read(b[i]);
	for(int i=0;i<n;i++){
		res1+=win[a[i%n_a]][b[i%n_b]];
		res2+=win[b[i%n_b]][a[i%n_a]];
	}
	write(res1),putchar(' '),write(res2);
	return 0;
}

Attention

这里一定注意输入 a 数组和 b 数组时为 i=0,而非 i=1i=1已经试验过了

原因是因为在后面记录分数时,我们的 win 数组是从 win[0][0] 开始记录的,加分时 i%n_a 必定会出现为 (0) 的情况。

原文地址:https://www.cnblogs.com/-pwl/p/14025487.html