- 【题目】
n个人围成一圈报数(n>=3),报数报到3的人退出圈子,请问最后留下来的人的编号和其所报的数
————————————————————————————————————————————————
【心得】
这是一道练习一二级指针应用和链表的增删改查的好题,前后多次修改,感觉对指针的理解和单链表的掌握都有了较大的提高
过程当中得到了杨柳老师的午饭都没吃的帮助,老师人超nice的,以后还是不要再饭点去院楼问问题了
另外老师建议可以对链表中的人报3后就赋值0(数据域bs=0),然后用分枝跳过这些人,避免写删除函数,但是个人觉得还是无脑模拟过程爽
———————————————————————————————————————————————
【代码】c++实现
#include<iostream>
using namespace std;
struct node{
int num;
int bs;
node* next;
};
int length(node* rhead);
void del(node* rhead,node** p_rhead);
void renum(node* rhead);
void print(node* rhead);
int main(){
int n;
cin>>n;
node* head=new node;
node* rhead=head;
head->next=NULL;
int temp=0;
for(int i=0;i<n;i++){
node* p=new node;
temp++;
if(temp>3)temp-=3;
p->bs=temp;
p->num=i+1;
head->next=p;
head=p;
if(i==n-1)p->next=rhead->next;
else p->next=NULL;
}
node* rtemp=rhead;
rhead=rhead->next;
delete rtemp;
while(length(rhead)>=3){
del(rhead,&rhead);
renum(rhead);
}
print(rhead);
return 0;
}
int length(node* rhead){
int len=0;
node* p=rhead;
do{
len++;
p=p->next;
}while(p!=rhead);
return len;
}
void del(node* rhead,node** p_rhead){
node* p=rhead,*bs1=NULL;
do{
if(p->next->bs==3){
node* temp=p->next;
p->next=p->next->next;
bs1=temp->next;
delete temp;
}
p=p->next;
}while(p!=rhead);
*p_rhead=bs1;
}
void renum(node* rhead){
node* p=rhead;
int temp=0;
do{
temp++;
if(temp>3)temp-=3;
p->bs=temp;
p=p->next;
}while(p!=rhead);
}
void print(node* rhead){
node* p=rhead;
cout<<"The surviving people:"<<endl;
do{
cout<<"num="<<p->num<<' '<<"bs="<<p->bs<<endl;
p=p->next;
}while(p!=rhead);
}