游戏【中石油】

题目描述

今天是星期天,小楠楠来找你玩“石头、剪刀、布游戏”。你正在学习信息学,所以想了一种需要编程来玩的“石头、剪刀、布游戏”。首先,用数字1,2,3分别表示出石头、剪刀、布。其次,你确定自己前N次“石头、剪刀、布”的出拳方法,下面N次再次同样出拳,…,周而复始;也要求楠楠确定他前M次的出拳方法,然后周而复始。问第K次后,你赢了几次?
例如:N=4,你的前4次出拳方式是“石头、剪刀、布、布”,用数字表示即:”1 2 3 3”。M=5,楠楠前5次出拳方式是“剪刀、石头、石头、布、布” ,用数字表示即:”2 1 1 3 3”。K=10时,情况如下表:

在这里插入图片描述

你共赢了5次。

输入

第一行3个整数N,M,K。分别表示你出拳方式的周期长度、楠楠出拳方式的周期长度和总共玩的次数。
第二行有N个整数,每个整数为1、2、3其中之一。
第三行有M个整数,每个整数为1、2、3其中之一。

提示

8个数据: N,M 的范围是[1..100],K的范围是[1…100,000]。
2个数据:   N,M的范围是[1..100],K的范围是[1…1,000,000,000]

本题的数据量很大,主要考察了对时间复杂度的处理,不能进行暴力从0到k遍历下去,时间复杂度会太大,因为N,M是有周期的,我们只需要找到他们之间的最小公倍数,这就是他们的一个最小正周期,每一次经过这一个周期都会有一个固定的值,到最后让结果先加上几个正周期的结果,然后让总次数减去周期*周期个数,最后再单独算剩下的情况,加上就行了,答案就是最小公倍数比较次数乘以k/最小公倍数+k%最小公倍数比较次数

 

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
	ios::sync_with_stdio(0);//可以抵消cin和scanf之间效率的差别
	cin.tie(0);
	cout.tie(0);
	int a[101] = { 0 };
	int b[101] = { 0 };
	long long int m, n, o, count = 0, count1 = 0;
	cin >> m >> n >> o;
	for (int i = 0; i < m; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
	}
	int temp = max(m, n);//求最小公倍数,即最小正周期
	for (int i = temp;; i++) {
		if (i % n == 0 && i % m == 0) {
			temp = i;
			break;
		}
	}
	int j = 0, k = 0;
	for (int i = 0; i < o % temp; i++) {//多出来的部分
		if (a[j] == 1 && b[k] == 2 || a[j] == 2 && b[k] == 3 || a[j] == 3 && b[k] == 1) {
			count1++;
		}
		j++;
		k++;
		if (j == m) {
			j = 0;
		}
		if (k == n) {
			k = 0;
		}
	}
	for (int i = 0; i < temp; i++) {//一个周期内获胜次数
		if (a[j] == 1 && b[k] == 2 || a[j] == 2 && b[k] == 3 || a[j] == 3 && b[k] == 1) {
			count++;
		}
		j++;
		k++;
		if (j == m) {
			j = 0;
		}
		if (k == n) {
			k = 0;
		}
	}
	cout << count * (o / temp) + count1;
	return 0;
}

 这是暴力遍历和优化后时间复杂度的差别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱康代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值