#include<bits/stdc++.h> using namespace std; int people[105]={0}; int main() { int n,m; cin>>n>>m; int sum=0; int f=0;//出圈人数 while(f!=n){//所有人出圈 for(int i=1;;i++){//枚举圈中所有位置 if(i>n){ i=1;//首尾相连 } if(!people[i]){ sum++;//有人则报数 +1 } if(sum==m){//报数为M sum=0; cout<<i<<" "; people[i]=1;//出圈 f++; }} } }
时间: 2025-06-27 18:06:24 AIGC 浏览: 25
这段代码的功能是模拟约瑟夫环(Josephus Problem)问题,即给定 \( n \) 个人围成一圈,并从某一个人开始报数,每报到第 \( m \) 的人就出圈,直到所有人都出圈为止。
然而,在当前的代码中有几个潜在的问题或改进点:
### 当前代码中的问题:
1. **无限循环的可能性**:`for (int i = 1; ; i++)` 这个写法可能导致死循环。虽然你在内部有条件判断 `if (!people[i])` 和 `sum == m` 来控制逻辑流,但如果某些条件没有正确处理,可能会导致程序卡住。
2. **效率较低**:由于每次都需要遍历整个数组并且手动检查是否已经出圈 (`!people[i]`) ,因此性能较差。
3. **可读性和结构化不足**:部分逻辑嵌套过深且缺少注释说明,使得维护困难。
### 改进后的版本
以下是对上述问题进行优化后的一个完整实现方案:
```cpp
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
bool inCircle[MAXN]; // 标记每个人的状态: true表示还在圈子内, false表示已离开
void solve(int n, int m){
memset(inCircle, true, sizeof(bool)*MAXN); // 初始化所有人都是在圈子里
int countOut = 0; // 记录总共出局的人数
int currentPos = 0; // 指针指向当前位置(从0开始编号)
while(countOut != n){
int stepCount = 0;
// 找到第m个人并让他出圈
do {
if(inCircle[currentPos]){
stepCount++; // 如果这个人还没被淘汰,则增加计步器
if(stepCount == m){
cout << (currentPos+1) << " "; // 输出该人的序号(+1转换为自然顺序)
inCircle[currentPos] = false; // 将此人状态改为false(退出圈子)
countOut++; // 出局人数加一
break; // 已经找到目标人物了,跳出本次do-while寻找过程
}
}
// 更新下一个位置索引,考虑循环边界情况(n取模运算保证回到起点)
currentPos = (currentPos + 1)%n ;
} while(true);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, m;
cin >> n >> m ;
solve(n , m );
}
```
---
#### 给出解释
在这个改进版中做了以下几个方面的修改与增强:
1. 使用了一个布尔类型的辅助数组 `inCircle[]` 替代原代码里的整型数组 `people[]`, 更符合实际意义同时节省空间开销.
2. 增设变量 `countOut` 明确统计目前有多少成员已经被移除, 较之之前通过简单累加标记的方式更直观可靠.
3. 引入 `stepCount` 变量用来精确记录当前连续经过但尚未被选中的有效个体数目;这有助于避免多余的重复操作及可能引发的错误判定.
4. 利用标准库函数如 `memset()` 快速初始化数据区域值,默认将每位设置存在标志位true.
此外还添加了一些必要的头文件管理、以及更快的标准输入输出模式调优(`ios::sync_with_stdio(false)` 和 `cin.tie(NULL)`)等技巧提高运行速度尤其针对大规模测试案例时非常有用。
---
阅读全文
相关推荐



















