题目:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到只剩下一个人为止。
输入:n,m (m < n)
输出:剩下最后一个人的编号
#include <iostream>
#include<malloc.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
int main(void)
{
int n, m; //n参加人数,数到m的人出列
int i, count = 1;
struct node *head, *tail, *p, *q, *newNode;//p指向当前处理的结点,q总是指向p指针指向的前一个结点
head = (struct node *)malloc(sizeof(struct node));//创建头节点
head->next = NULL;
tail = head;
cin>>n;
cin>>m;
if (n == 0 || m == 0)
{
free(head);
}
else
{
for (i = 0; i < n; i++)//采用尾插法构建循环链表,用tail指针指向最后一个结点
{
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = i + 1;
tail->next = newNode;
newNode->next = head->next;
tail = newNode;
}
q = tail; //前结点
p = head->next; //后结点
while (q != p) //pq总是一前一后,一旦相遇,说明只剩一个结点了
{
if (count == m)
{
q->next = p->next;
free(p);
p = q->next;//将p移动到下一个有效的结点上
count = 1;
}
else
{
q = p; //pq各自向后移动一个结点,q总在p之前
p = p->next;
count++;
}
}
cout<<p->data<<endl;
free(p);
}
return 0;
}
运行结果: