今天徒弟问了我这样的一个问题,当时想了很久才把他解决了。其实也不是什么很难得问题,主要是自己的思维被局限了。被局限到那些所谓的库了,比如STL什么的了。所以一时没有想到什么好办法,后来才想到用循环链表去解决它。
下面就来学习下这个问题吧。
编号为1 ,2 ,3 …..,n的n个人按顺时针方向围坐成一圈,每个人持有一个密码,现在给定一个随机数m> 0 , 从编号为1的热开始,按照顺时针顺序从1开始报数。报到m时停止,报m的人出去,同时留下密码作为新的随机数,然后从他的下一个开始重新从1技术,如此下去,直到所有的人全部出来为止。
具体代码其实是很简单的。下面就来看下吧。唯一的难点就是循环链表的遍历。
#include <iostream>
using namespace std;
/*人物的定义,包含自己的编号,所持的密码,和指向下一个的指针*/
struct Person
{
int num;
int cipher;
Person * next;
};
Person person[7];
int main()
{
//先对所有的属性赋值
for (int i = 0; i<7; i++)
{
person[i].num = i + 1;
person[i].next = &person[i + 1];
}
person[6].next = &person[0];//使最后一个人物的指针指向第一个,构成循环链表
person[0].cipher = 3;
person[1].cipher = 1;
person[2].cipher = 7;
person[3].cipher = 2;
person[4].cipher = 4;
person[5].cipher = 8;
person[6].cipher = 4;
int m = 20;//开始时输入的起始密码值
Person * currentPerson;//方便对人物链表的搜索
Person * prePerson;
currentPerson = &person[0];//开始时将指针指向人物的第一个和最后一个,因为是循环链表
prePerson = &person[6];
while (currentPerson != prePerson)
{
for (int i = 1; i<m; i++)//移动指针,使其指向需要移出的人物,如果m = 7,就需要执行6次操作,所i从1开始的,而不是0开始的
{
prePerson = currentPerson;
currentPerson = currentPerson->next;
}
m = currentPerson->cipher;
cout << currentPerson->num << " ";//输出人物的编号
prePerson->next = currentPerson->next;//修改链表,使选定的人物移出
currentPerson = prePerson->next;
}
cout << currentPerson->num;//输出最后一个人物的编号
getchar();
return 0;
}