#经典算法——约瑟夫环
问题描述: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;
}