上周生病住院了,所以没有发(。・_・。)ノI’m sorry~
作业题:题目描述
𝑛n 个人围成一圈,从第一个人开始报数,数到 𝑚m 的人出列,再由下一个人重新从 11 开始报数,数到 𝑚m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
输入格式
输入两个整数 𝑛,𝑚n,m。
输出格式
输出一行 𝑛n 个整数,按顺序输出每个出圈人的编号。
AC循环双向链表代码:
#include <iostream>
typedef long long Int;
struct Node {
Int x; // 节点的号
Node* right; // 指向下一个节点的指针
Node* left; // 指向上一个节点的指针
};
Int N,M;
int main() {
Node* head = new Node{1, head, head};
std::cin >> N>>M;
Node* i;
Int j;
for (i = head, j = 1; j < N; j++, i = i->right) {
i->right = new Node{j + 1, head, i};//向i的右边添加一个元素,它的编号为j+1(因为1已经有了)左边是i,右边是head(每次都向链表尾部添加节点)
}
head->left=i; // 将头节点的left指针指向最后一个节点,这个操作在for里面无法实现
i=head; // 将指针i指向头节点
// 开始游戏
for(Int z=1;z<N;z++){//刻意少写了一个节点,因为最后一个节点要特殊处理
for(Int p=2;p<=M;p++){
i=i->right; // 将指针i向右移动M-1次因为往后移3格只需要移2次,因为i当时已经取了下一个了
}
std::cout<<i->x<<' '; // 被删除节点的编号
Node *left=i->left; // 存储被删除节点的左节点和右节点
Node *right=i->right;
delete i; // 删除当前节点
i=right; // 将指针i指向右节点
left->right=right; //将链表接上
right->left=left;
}
for(Int p=1;p<=M;p++){
i=i->right;
}
std::cout<<i->x<<' '; // 输出最后一个节点的值,不用接了,因为删除了它链表里就没有元素了删了会挂
delete i; // 删除最后一个节点
return 0;
}
递归之链表的寻找元素,计数,创建
#include <iostream>
typedef long long Int;
struct Node {
Int x; // 节点的编号
Node* right;
Node* left;
};
// 获取链表中第n个节点的指针
Node* output(Node* head, Int n) {
if (n == 1) { // 如果是第一个节点,直接返回头指针
return head;
}
// 否则递归获取下一个节点的指针
return output(head->right, n - 1);
}
// 计算链表中节点的个数
Int count(Node* head) {
if (!head) { // 如果链表为空,返回0
return 0;
}
// 否则递归计算下一个节点的个数,并加上当前节点
return 1 + count(head->right);
}
// 新建一个长度为n的链表,每个节点的值为从x开始的编号
void make(Node* head, Int n, Int x = 1) {
// 如果n为0,直接返回空指针
n == 0 ? nullptr : new Node{x, nullptr, nullptr};
if (n > 1) {
// 递归新建下一个节点,他的
make(head->right, n - 1, x + 1);
head->right->left = head;
}
}
// 新建一个长度为n的链表,每个节点的值为从x开始的编号
void make(Node* head, Int n, Int x = 1) {
// 如果n为0,直接返回空指针
n == 0 ? nullptr : new Node{x, nullptr, nullptr};
if (n > 1) {
// 递归新建下一个节点,并将当前节点作为下一个节点的前驱
make(head->right, n - 1, x + 1);
head->right->left = head;
}
}