分享做题过程中的一些记录
有个游戏是这样的:首先,让参与者围成一个大圈。然后,随机指定一个数m,让编号为0的人开始报数。每次喊到m-1的那个人要出列,并且不再回到圈中,从他的下一个人,继续0...m-1报数....这样下去....直到剩下最后一个人。请你试着想下,哪个参与者会留到最后呢?(注:参与者编号是从0到n-1)
输入为两个数字n和m
输出为一个整数,表示最后剩下的人的编号
经典的约瑟夫环问题,现分别采用链表和数组方式解决
方法一:数组
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
int* p = new int[n];
for (int i=0; i < n; i++)
{
p[i] = i + 1;
}
int count = n; //count是还剩的人数
int process = -1;//process是进行位置
while (count > 1)
{
for (int n0 = m; n0 > 0;)
{
process++;
if (process > n - 1)
{
process = process % n;
}
if (p[process] != 0)
{
n0--;
}
}
if (process > n - 1)
{
process = process % n;
}
p[process] = 0;
count--;
for (int i = 0; i < 5; i++)//展示过程 检验用
{
cout << p[i] << " ";
}
cout << endl;
}
for (int i = 0; i < n; i++)
{
if (p[i] != 0)
{
cout << i;
break;
}
}
return 0;
}
过程步骤分析:
1、动态申请一个数组
2、模拟人工方法进行处理
经验强调:
1、为了补齐循环节,可以注意初始化,适当增长首个循环节长度
2、适当使用检验代码 具象整个过程
方法二:链表
#include <iostream>
using namespace std;
struct Circle
{
int code;
Circle *next;
};
void Creat(Circle*& head,int n)
{
Circle * q;
head = new Circle;
q = head;
for (int i = 0; i < n; i++)
{
q->code = i;
if (i < n - 1)
{
q->next = new Circle;
q = q->next;
}
}
q->next = head;
}
void Out(Circle*& head, int m)
{
Circle* p, *q;
q = head;
p = q->next;
while (q->next != q)
{
for (int i = 1; i < m-1; i++)
{
q = p;
p = p->next;
}
q->next = p->next;
delete p;
p = q->next;
q = p;
p = p->next;
}
cout << q->code;
}
int main()
{
int m, n;
cin >> n >> m;
Circle* head;
Creat(head,n);
Out(head, m);
return 0;
}
过程步骤分析:
1、真实模拟一个圈的情况,通过逐个删除链节的方式进行处理,当判断最终剩余一个链节时结束并输出最终结果。
经验总结:平时多练练函数,会让自己的代码变得好看一些(?)
结尾:只是菜菜日常练习中的一些总结,用来督促自己勤奋做题,欢迎大佬指点指正,感激不尽!