沃瑟夫问题:约瑟夫问题的变体
#include <bits/stdc++.h>
using namespace std;
const int size = 5001;
int n, front = 1, rear = size;
int q[size + 1];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
rear = rear % size + 1;
q[rear] = i;
}
int x = 0, i = 1;
while (rear % size + 1 != front) {
int y = q[front];
front = front % size + 1;
x++;
if (x == i * i) {
printf("%d ", y);
x = 0;
i++;
} else {
rear = rear % size + 1;
q[rear] = y;
}
}
return 0;
}
因为n 最大是5000,一个for,一个while会超时间复杂度(1s)
希望帮助改良代码
【以下回答由 GPT 生成】
这段代码中有两个循环会导致超时问题,一个是for
循环,一个是while
循环。下面是对代码的改进建议:
使用std::queue
代替数组:当前代码使用数组来模拟队列,但是使用动态数组会导致较慢的性能。C++标准库中的std::queue
提供了队列数据结构,并且封装了实现细节,可以提供更高效的队列操作。因此,建议使用std::queue
代替数组实现队列。
避免使用std::endl
:当前代码在输出时使用了printf
配合std::endl
来刷新输出缓冲区。然而,std::endl
会在遇到换行符时强制刷新输出缓冲区,在循环中频繁使用会导致性能下降。替代方案是使用换行符"\n"来换行,然后使用std::flush
手动刷新输出缓冲区。
下面是根据上述建议改进后的代码:
#include <iostream>
#include <queue>
#include <cmath>
int main() {
int n;
std::cin >> n;
std::queue<int> q;
for (int i = 1; i <= n; i++) {
q.push(i);
}
int x = 0, i = 1;
while (!q.empty()) {
int y = q.front();
q.pop();
x++;
if (x == i * i) {
std::cout << y << " ";
x = 0;
i++;
} else {
q.push(y);
}
}
std::cout << std::flush;
return 0;
}
以上是改进后的代码,通过使用std::queue
来代替数组实现队列,并在输出时使用换行符"\n"来换行,然后使用std::flush
手动刷新输出缓冲区,可以有效提高代码的性能。
其实可以用一个循环,先设置一个给定长度的数组,然后先将这个数组里的元素都赋值为0。然后就可以设置一个temp,用来记录已经出列的人数,然后利用一个while循环。第一次的话,就是将这个a0变为1,然后temp自增;接着每次的话就是这个索引都增加i的平方。 然后就是判断越界的条件是什么,如果他越界的话,就是先让他的这个索引变为从0开始第一个没有出列的人。然后再次判断。每次循环输出一个,或者存下来最后输出