围圈报数问题:
写法一:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int delet;//表示删除的数量初始化是0
int a[1000];
int count=0;//报数器
for(int i=0;i<n;i++)
a[i]=1;//将所有的猴子标记成1
while(delet<n-1)
{
for(int i=0;i<n;i++)
{
if(a[i]==0)//判断条件当前是0则进行下一次内层循环
continue;
count ++;//否则报数器加一
if(count==3)
{
a[i]=0;//将报数为3的猴子标记成0
count=0; //恢复现场
delet++;//删除数量加1
}
}
}
for(int i=0;i<n;i++)
{
if(a[i]==1)//遍历出标记为1的则是要找的
cout << i+1;//因为数组下标从0开始所以加上1
}
return 0;
}
写法二: (列表+迭代器)
#include <iostream>
#include <list>
using namespace std;
int main()
{
int n;
cin >> n;
list<int> people;
for (int i = 1; i <= n; ++i)
people.push_back(i); // 初始化链表,1到n号人
auto it = people.begin(); // 迭代器指向链表头部
while (people.size() > 1) // 只有当链表中还有人时进行循环
{
for (int i = 0; i < 2; ++i) // 每次跳过两个人
{
++it;
if (it == people.end()) // 如果到达链表末尾,则回到链表头部
it = people.begin();
}
it = people.erase(it); // 删除当前位置的人,并返回下一个位置的迭代器
if (it == people.end()) // 如果删除的是链表末尾的人,则回到链表头部
it = people.begin();
}
cout << *people.begin(); // 输出剩下的唯一一个人的编号
return 0;
}
不一样的围圈报数问题:
写法一:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main() {
int t, n; // t 用来存储测试用例的数量
cin >> t; // 读取测试用例的数量
while(t--) { // 对于每个测试用例
cin >> n; // 读取该测试用例中的猴子数量
int delet = 0; // 表示删除的数量,初始化是0
int a[1000] = {0}; // 初始化所有猴子为未标记状态(0表示未标记,1表示标记)
int count = 0; // 报数器
// 填充数组,假设猴子从1到n编号,且初始时都活着(即标记为1)
for(int i = 0; i < n; i++) {
a[i] = 1;
}
循环直到只剩一个猴子或所有猴子都被标记为死亡
while(delet < n ) { // 注意:当没有猴子时,循环应该结束
for(int i = 0; i < n; i++) {
if(a[i] == 0) // 如果当前猴子已死亡,则跳过
continue;
count++; // 报数器加一
if(count == 3) { // 如果报数到3
a[i] = 0; // 标记当前猴子为死亡
cout << i + 1 << " "; // 输出被标记为死亡的猴子的编号
count = 0; // 重置报数器
delet++; // 死亡数量加1
}
}
}
cout << endl; // 每个测试用例结束后输出一个换行符
}
return 0;
}
写法二:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 55;
int n;
int ne[N];//定义了一个整型数组 ne,用于存储每个节点的下一个节点的编号。
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n;
//初始化环形链表直到n-1
for(int i=1;i<n;i++) ne[i]=i+1;
//使得每个节点指向下一个节点,即 ne[i] 存储的是节点 i 的下一个节点的编号。
ne[n]=1;//使最后一个节点指向第一个节点,形成闭环。
int p=n;//定义一个整型变量 p,表示当前节点的编号,初始化为循环链表中的最后一个节点的编号。
for(int i=0;i<n;i++)
{
p=ne[ne[p]];//更新当前节点的编号,使其指向下一个节点的下一个节点。
cout << ne[p] << ' ';//输出当前节点的下一个节点的编号。
ne[p]=ne[ne[p]];
// 的作用就是将当前节点的下一个节点更新为下下个节点。
//这行代码实现了删除当前节点的下一个节点的操作,从而实现了节点的删除。
}
cout << endl;
}
return 0;
}