使用数组实现约瑟夫环问题的写法:
#include <iostream>
#include <vector>
using namespace std;
vector<int> josephus(int n, int m) {
vector<int> res; // 存储出列顺序
vector<bool> used(n, false); // 标记每个人是否已经出列
int count = 0, index = -1; // count表示当前报数的人数,index表示当前报数的人的下标
while (res.size() < n) { // 循环直到所有人都出列为止
index++; // 按顺序遍历人数列表
if (index >= n) index = 0; // 处理超出范围的情况
if (!used[index]) count++; // 如果这个人还没有出列,则更新计数器
if (count == m) { // 如果这个人需要出列
res.push_back(index + 1); // 将他的编号存储在出列顺序列表中
used[index] = true; // 标记这个人已经出列
count = 0; // 重置计数器
}
}
return res;
}
int main() {
int n, m;
cin >> n >> m;
auto res = josephus(n, m);
for (auto x : res) {
cout << x << " ";
}
cout << endl;
return 0;
}
这段代码的基本思想和前面使用链表的实现类似,都是通过不断遍历和删除节点来模拟约瑟夫环问题的解。具体来说:
1. 首先,在函数josephus()中,使用一个vector<bool>数组used来标记每个人是否已经出列,另一个vector<int>数组res来存储出列顺序。
2. 接着,通过while循环模拟报数和出列的过程,直到所有人都出列为止。具体地,按顺序遍历人数列表,更新计数器count,如果需要出列则将该人的编号存入出列顺序列表res中,并将其标记为已出列。
3. 最后,返回出列顺序列表res,并在main函数中输出结果。
需要注意的是,由于这里使用了bool类型的标记数组,所以在判断一个人是否已经出列时,可以直接用!used[index]来代替used[index] == false。此外,为了保持一致性,我们将每个人的编号从1开始计,输出时也要记得加1。
公众号:奇牛编程