围成圈圈报数游戏
在天勤oj上面有题目1368,是对循环链表的应用,当然用数组也可以做出来。
此处只解释用循环链表的解法。
这是原题的要求,为了更突出循环链表的特点,题目要求:N个人围成一圈循序编号,从1号开始按1,2,3顺序报数,按照先顺时针报X者退出圈外,其余的人在原来的圈圈的基础上,再从X后一个人开始按逆时针报Y者退出圈外。然后在其余的人围成的圈圈的基础上,按照从Y后的一个人开始顺时针报X者退出圈外,其余人在原来的圈圈的基础上,再按从退出者后一个人开始逆时针报Y者退出圈外,以此类推,输出最后剩余的人原来的编号。
先奉上代码:
输出:10
这道题实现了对循环链表的创建和删除操作。。。
学以致用。。。
此处只解释用循环链表的解法。
题目描述
N 个人围成一圈顺序编号,从1 号开始按1、2、3 顺序报数,报3 者退出圈外,其余的人再从1、2、3 开始报数,报3 的人再退出圈外,依次类推。请按退出顺序输出每个退出人的原序号。要求使用环行链表编程。
先奉上代码:
#include<iostream>
using namespace std ;
struct Node {//循环链表结点结构体
int data ;
Node *pre ;
Node *next ;
};
typedef Node *LinkList ;//线性表
void Create( LinkList &L, int n) { //创建双向循环链表存储的线性表
LinkList s ,h,p;
L=NULL ; //初始化链表为空
s=new Node ;//定义结点
h=s ;
for( int i=n; i>0;i-- ) { 把1—n存入链表中
s->pre=L ;
s->data=i ;
p=new Node ;
s->next=p ;//s结点的*next指向p 结点
L=s ; //L结点指向s结点
s=p ; //s 结点指向p结点
}
L->next=h ;
h->pre=L ;
}
int Delete( LinkList &L , int x , int y ) { //对循环链表中第X和第Y结点进行删除操作
for(int i=2;i<=x;i++ )
L=L->pre ; //L结点前移
L->pre->next=L->next ;
L->next->pre=L->pre ;
L=L->next ;
if(L->next==L->pre)
return L->next->data ;
for(int j=2;j<= y;j++ )
L=L->next ;
L->pre->next=L->next ;
L->next->pre=L->pre ;
L=L->pre ;
if(L->next==L->pre)
return L->next->data ;
else
return Delete( L,x,y ) ;
}
int main() {
int n,x,y ;
cin>>n>>x>>y ;
LinkList L ;
Create( L,n ) ;
cout<<Delete( L,x,y )<<endl;
return 0 ;
}
输入:10 3 2
输出:10
这道题实现了对循环链表的创建和删除操作。。。
学以致用。。。