经典问题——约瑟夫环

#经典算法——约瑟夫环
问题描述:N个人围成一个圈,从第一个人开始报数,报道k的人出列;剩下的人重新从1开始报数,报道k的人出列;重复此操作,直到所有人都出列为止。(输出出列的人的位置)

这里用循环的方法来解决问题:
1.循环是否结束,取决于圈内是否还有人。用m来表示总人数,每出圈一个人m - 1。
while(m > 0)即可
2.每个人都有两种不同的状态,在圈内和不在圈内,这里在圈内我们用0来表示,不在圈内用1来表示,开一个数组来存储这个状态, 再用一个num变量表示计数器,再圈内num + 1, 不在圈内num + 0.
3. i = (i + 1) % n 判断是否需要重新从头开始循环数组。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010;

int a[N], h[N];
int n;

int main() {
	memset(h, 0, sizeof h); // 将一个数组里的元素全都初始化为0
	
	int k;
	cin >> n >> k;
	
	for (int i = 0; i < n; i ++)
		a[i] = i + 1;
	
	int i = 0; // 下标
	int sum = n; // 总人数
	int num = 0; // 计数器
	while (sum > 0) {
		num += 1 - h[i];
		if (num == k) { // 这一步共分为四小步 
			cout << i << ' '; // 输出出圈人的位置
			h[i] = 1; // 给出圈人打个标记
			sum --; // 总人数减一
			num = 0; // 计数器重新重0开始 
		}
		i = (i + 1) % n; 
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值