CCF 201712-2游戏

题目描述

问题描述
  有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
  游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当n=5, k=2时:
  1号小朋友报数1;
  2号小朋友报数2淘汰;
  3号小朋友报数3;
  4号小朋友报数4淘汰;
  5号小朋友报数5;
  1号小朋友报数6淘汰;
  3号小朋友报数7;
  5号小朋友报数8淘汰;
  3号小朋友获胜。

给定n和k,请问最后获胜的小朋友编号为多少?
输入格式
  输入一行,包括两个整数n和k,意义如题目所述。
输出格式
  输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
  对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。

题解1

模拟题意,注意处理起始队列只有1个人的特殊情况。每次到达队尾需要判断当队列中的人数是否为1,是的话就达到结束条件,否则回到队首,继续执行相关操作。

代码1

#include<bits/stdc++.h> 
using namespace std;

#define MAX (1000 + 5)
bool mark[MAX];
int getNum(int n, int &res){//获取当前队列中的人数 
	bool flag = false;
	int cnt = 0;
	for(int i = 1; i <= n; ++i){
		if(!mark[i]){
			if(!flag){
				res = i;
				flag = true;
			}
			++cnt;
		}
	}
	return cnt;
}
int deal(int n, int k) {
	int num = 0, idx = 1, res = 0;
	while(true){
		if(getNum(n, res) == 1){//处理1 k等特殊情况 
			break;
		}
		if(!mark[idx]){//未出队 
			++num;
			if(num % k == 0 || num % 10 == k){//末数为k或者数为k的倍数 
				mark[idx] = true;
			}
		}
		if(idx == n){//到尾的时候考虑是否满足只有一个人的结束条件 
			if(getNum(n, res) == 1){
				break;
			}
			idx = 1;
		}
		else{
			idx = idx + 1; 
		}
	}
	return res;
}
int main(){
	//freopen("E://a.txt", "r", stdin);
	memset(mark, false, sizeof(mark));//初始化 
	int n, k;
	scanf("%d%d", &n, &k);
	printf("%d\n", deal(n, k));
	return 0;
}

题解2

使用2个队列来模拟

代码2

#include<bits/stdc++.h> 
using namespace std;

int deal(int n, int k) {
	queue<int>que[2];
	for(int i = 1; i <= n; ++i){//初始化队列
		que[0].push(i);
	}
	int cnt = 0, frt;
	while(que[0].size() + que[1].size() > 1){
		int idx = 0;
		while(que[idx].empty())idx++;//寻找非空的队列
		while(!que[idx].empty()){//报数出队
			++cnt;
			frt = que[idx].front();
			que[idx].pop();
			if(cnt % k != 0 && cnt % 10 != k){//未出队存放在另一个队列中
				que[1 - idx].push(frt);
			}
			if(que[idx].size() + que[1 - idx].size() == 1){//处理2 1 的情况
				break;
			}
		}
	}
	int idx = 0;
	while(que[idx].empty())idx++;
	return que[idx].front();
}
int main(){
	//freopen("E://a.txt", "r", stdin);
	int n, k;
	scanf("%d%d", &n, &k);
	printf("%d\n", deal(n, k));
	return 0;
}

github地址

发布了152 篇原创文章 · 获赞 29 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/happyeveryday62/article/details/103255158