第五题 游戏(game)
问题描述:
今天是星期天,小楠楠来找你玩“石头、剪刀、布游戏”。你正在学习信息学,所以想了一种需要编程来玩的“石头、剪刀、布游戏”。首先,用数字 1,2,3 分别表示出石头、剪刀、布。其次,你确定自己前 N 次“石头、剪刀、布”的出拳方法,下面 N 次再次同样出拳,…,周而复始;也要求楠楠确定他前 M 次的出拳方法,然后周而复始。问第 K 次后,你赢了几次?
例如:N=4,你的前 4 次出拳方式是“石头、剪刀、布、布”,用数字表示即:”1
2 3 3”。M=5,楠楠前 5 次出拳方式是“剪刀、石头、石头、布、布” ,用
数字表示即:”2 1 1 3 3”。K=10 时,情况如下表:
轮次 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
… |
你出拳 |
1 |
2 |
3 |
3 |
1 |
2 |
3 |
3 |
1 |
2 |
… |
楠楠出拳 |
2 |
1 |
1 |
3 |
3 |
2 |
1 |
1 |
3 |
3 |
… |
赢 |
√ |
|
√ |
|
|
|
√ |
√ |
|
√ |
… |
你共赢了 5 次。
输入格式:
第一行 3 个整数 N,M,K。分别表示你出拳方式的周期长度、楠楠出拳方式的周期长度和总共玩的次数。
第二行有 N 个整数,每个整数为 1、2、3 其中之一。
第三行有 M 个整数,每个整数为 1、2、3 其中之一。
输出格式:
一个整数,表示 K 轮出拳后,你赢的次数。
输入样例: |
|
|
| ||
5 |
6 |
100 |
|
|
|
1 |
3 |
2 |
2 |
1 |
|
3 |
3 |
1 |
1 |
1 |
2 |
输出样例 |
|
|
| ||
29 |
|
|
|
| |
数据范围: |
|
|
| ||
8 |
个数据: N,M 的范围是[1..100],K 的范围是[1…100,000]。 | ||||
2 |
个数据: |
|
N,M 的范围是[1..100],K 的范围是[1…1,000,000,000] |
(友情提示)整数数组开的太大(比如 30,000,000)可能会因超空间而得 0 分。
题目意思就是要我们求k轮后,自己赢的次数。因为自己和楠楠的出拳方式是一直固定的,所以只需枚举就行了。但直接枚举肯定超时。因为自己的出拳方式和楠楠的出拳方式的周期不同,所以又延伸出一个周期问题。转变过来就是成了找最小公倍数的问题。
找最小公倍数时,我们又可以运用一种快捷方法,辗转相除法。
辗转相除法求两个数的最大公约数的步骤如下:
先用另一个数除以一个数,得第一个余数;
再用上一次的除数除以第一个余数,得第二个余数;
又用上一次的除数除以第二个余数,得第三个余数;
这样逐次上一次除数除以前一个余数,直到余数是0为止.那么,最后一个除数就是所求的最大公约数。
最大公倍数即为两个数的积除以两个数的最小公约数。
算出在最小公倍数以内我胜利的回合,再用k除以最小公倍数以内我胜利的回合,就可算出k回合以内我赢的次数了。
如果k%最小公倍数以内我胜利的回合不为0的话,那么还需在一开始用个变量保存余数,在for循坏中找出当i等于余数时,用个变量c保存当前我胜利的次数,最后只需输出k除以最小公倍数以内我胜利的回合加上c即可。
程序如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int a,b,c,d[105],e[105],f,j,l,m,n,p,v,q,k,r;
bool vt(int o,int z)//用函数判断我是否赢了
{
if(o==3&&z==1)
return true;
else
if(o==1&&z==2)
return true;
else
if(o==2&&z==3)
return true;
else
return false;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
cin>>n>>k>>p;
a=n;
b=k;
c=a%b;
while(c!=0)//辗转相除法
{
a=b;
b=c;
c=a%b;
}
a=n*k/b;
b=p%a;
for(int i=1;i<=n;i++)
cin>>d[i];
for(int i=1;i<=k;i++)
cin>>e[i];
for(int i=1;i<=a;i++)//for循环算出最小公倍数以内我胜利的回合
{
f++;
j++;
if(vt(d[f],e[j]))
l++;
if (i==b)//用个变量c保存当前我胜利的次数
c=l;
if(f==n)
f=0;
if(j==k)
j=0;
}
cout<<l*(p/a)+c<<' ';
return 0;
}