🍄前言
大家好,我是一勺黑猫。今天是每日一题的第七天,欢迎更多小伙伴加入到我们的打卡计划中,希望和你们在学习算法的路上一起进步~
🙎作者简介:一个正在努力学算法和后端的大三girl
⏳每日一题打卡地:高校算法学习社区
🎈联系方式:157543570(qq)
🍄今日题目
🌰思路:这道题重点在于将出圈的位置去掉。我一开始想不到用什么数据结构,所以就使用visit数组记录每个位置是否出圈,对于已经出圈的位置跳过就好了。再用一个变量记录当前出圈的总人数,遍历到n时退出循环即可
🌰AC代码:
#include<iostream>
#include<vector>
using namespace std;
vector<int> v;
bool visit[100]; //记录每个位置是否出圈
int main() {
int n, m;
cin >> n >> m;
v.resize(n+1);
int cnt = 0,ans=0;
for (int i = 1;; i=(i+1)%n){
//已经出圈的位置就跳过
if (visit[i] == true)
continue;
//没出圈就计数
ans++;
//如果是m的倍数就输出,并将visit置为true
if (ans % m == 0) {
cout << (i==0?n:i) << " ";
visit[i] = true;
cnt++; //cnt记录当前出圈的总人数,到n时就结束循环
if (cnt == n)
break;
}
}
return 0;
}
🍄向大佬学习
🌰思路:看了洛谷的一些题解,有一个方法感觉很新奇,是用数组模拟链表,也就是用数组保存每个节点的后继节点的值,即next[1]=2,next[2]=3....next[n]=1。删除出圈节点就将前驱结点的值改成被删除节点的值,比如删除3号节点,我们将next[2]=3变成next[2]=4就可以了。
🌰大佬代码:
#include<iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int next[100]={0};
//初始化
for (int i = 0; i < n; i++)
next[i] = i + 1;
next[n] = 1;
int p = 0;
//开始模拟出圈过程
for (int i = 1; i <= n; i++) {
for (int j = 1; j < m; j++)
p = next[p];//p位置右移
cout << p[next] << " ";//输出出圈人的位置
next[p] = next[next[p]];//删掉出圈人
}
return 0;
}
PS:大佬的代码中,我发现输出的是p[next],这令我颇为惊讶,什么时候int型变量可以这么用了??询问后,有xd说p[next]等于*(p+next),而next[p]等于*(next+p),所以就等价了,emmm我觉得蛮有道理!自己又调试了一下,结果如图:
*(p+next)和*(next+p)确实是等价的,而p[next]在调试时不会给出值。不过程序却可以正常运行,实在百思不得其解,有知道的友友可以解答一下喔~