A. DS循环链表—约瑟夫环(Ver. I - A)
时间限制
1s
内存限制
128MB
题目描述
N个人坐成一个圆环(编号为1 - N),从第S个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2,S = 1。2号先出列,然后是1号,最后剩下的是3号。
要求使用循环链表实现。
输入
测试数据有多组
每组包括3个数N、K、S,表示有N个人,从第S个人开始,数到K出列。(1 <= N <= 10^6,1 <= K <= 10, 1 <= S <= N)
输出
出列的人的编号
输入样例1
13 3 1
3 2 1
输出样例1
3 6 9 12 2 7 11 4 10 5 1 8 13
2 1 3
该题主要考察数据结构循环链表的使用,在定义循环链表时,与普通单链表的定义不同的是,我们需要让尾结点指向头结点(不是head),这里需要用到的还有循环链表的删除操作,这也有与单链表不同的地方,我们需要特殊考虑//分为当链表中只有一个元素时,删除链表第一个结点(不是头结点),删除链表尾结点,其他情况,否则会出现丢失head的情况
这里分享一篇我看到的较好的文章C语言数据结构篇——单循环链表的创建,插入,节点删除,打印等操作_Demo不是emo的博客-优快云博客_循环单链表的创建
#include<iostream>
using namespace std;
class Node {
public:
int num;
Node* next;
Node() {
next = NULL;
}
};
class Clinklist {
public:
Node* head;
int len;
Clinklist() {
head = new Node();
head->next = NULL;
len = 0;
}
void create(int n) {
Node* p = head;
for (int i = 1; i <= n; i++) {
Node* node = new Node();
node->num = i;
node->next = p->next;
p->next = node;
p = p->next;
}
p->next = head->next;//创建循环链表的关键:让尾结点指向头结点(不是head)
len = n;
}
bool delNode(Node* target) {//注意这里需要分为四种情况讨论,否则会出现丢失头结点head的情况
//分为当链表中只有一个元素时,删除链表第一个结点(不是头结点),删除链表尾结点,其他
Node* pcur = head->next;//指向第一个结点(不是头结点)
Node* plast=head->next;//指向最后一个结点
while (plast->next != pcur) {
plast = plast->next;
}
if (len == 1) {
head->next = NULL;
}
else if (target == pcur) {
head->next = pcur->next;
plast->next = pcur->next;
}
else if (target == plast) {
Node* pre = pcur;
while (pre->next != plast) {
pre = pre->next;
}
pre->next = pcur;
}
else {
Node* pre = pcur;
while (pre->next != target) {
pre = pre->next;
}
Node* q = pre->next;
pre->next = q->next;
free(q);
}
return true;
}
bool getOut(int s,int k) {
if (!(s >= 1 && s <= len)) {
return false;//判断s是否合法
}
//先找到第s个人;
Node* p = head->next;
int i = 1;
while (i != s) {
p = p->next;
i++;
}
//开始报数
while (len != 1) {
int num = 1;
while (num != k) {
num++;
p = p->next;
}
cout << p->num << ' ';
Node* q = p;
p = p->next;//下一个人
delNode(q);//删除找到的结点
len--;
}
cout << p->num << endl;//最后一个人直接输出即可
return true;
}
};
int main()
{
Clinklist clinklist;
int n, k, s;
while (cin >> n >> k >> s) {
clinklist.create(n);
clinklist.getOut(s,k);
}
return 0;
}