h0181. 约瑟夫问题(pta题目)

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入格式:

每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:

0 0

输出格式:

对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

输入样例:

6 2
12 4
8 3
0 0

输出样例:

5
1
7

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

AC代码

思路:

主要是3个变量的维护,

  1. sum(统计剩余猴子数量)
  2. count(报数)
  3. cur(指向所有猴子,包括已经淘汰的)

对于这个圈,用数组来代替,数组下标对应猴子的编号,数组元素存1或者0(1未淘汰,0淘汰)

然后循环不停走(直到只剩一只猴子),当cur指向的是已经淘汰的,那么count不计数(相当于不报数),否则就count++(报数),报完发现count恰好到m了,就把cur指向的元素置0(淘汰),并且count置0(剩下猴子重新报数),并且sum--(淘汰一只)。

最后注意cur一直往后走,走到数组末尾时重新从0开始(因为是个循环的圈)

#include<iostream>
using namespace std;
const int MAX = 305;
int main() {
	int n, m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) break;
		int arr[MAX] = { 0 };
		for (int i = 1; i <= n; i++) arr[i] = 1;//初始化数组,1未淘汰,0淘汰
		int sum = n, cur = 1, count = 0;//sum记录未淘汰猴数量,cur指向圈内所有猴(包括已经淘汰的),count是报的数
		while (sum > 1) {//不止一只猴时就继续报数淘汰
			if (arr[cur] == 1) {
				count++;//报数
				if (count == m) {//恰好报到m,淘汰该猴
					arr[cur] = 0;
					count = 0;//重新报数
					sum--;//猴数减一
				}
			}
			cur++;
			cur = (cur == n + 1) ? 1 : cur;//cur要循环走,所以指向数组末尾时回到起始
		}
		//循环找最后剩下那只猴
		for (int i = 1; i <= n; i++) {
			if (arr[i] == 1) {
				printf("%d\n", i);//注意输出的是猴的编号
				break;//肯定只有一只猴王,所以输出后直接跳出,争取一点效率。。
			}
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值