您的位置:首页 > 其它

CSDN 报数游戏-双向循环链表实现

2014-01-06 17:44 295 查看
通过这道题,对于链表的运用感觉灵活了许多……

有n个人编号1-n,按照顺时针方向围成一个圆圈。它们预先定义好两个整数x,y。先从1号顺时针方向开始报数,报到x的人出圈,再从x的逆时针方向的后一个人从1开始报数,报到y的人出圈,再从这个人的顺时针方向后一个人开始从1报数,报到x的人出圈,如此反复,直到最后剩下一个人为止,问最后剩下的那个人是几号?

比如n = 10, x = 3, y = 2,报数的过程如下

报数人 1, 2, 3 3出圈

报数人 2,1 1出圈

接着2,4 ,5 5出圈

接着4,2 2出圈

接着4,6,7 7出圈

接着6,4 4出圈

接着6,8,9 9出圈

接着8,6 6出圈

接着8,10,8 8出圈

剩余 10号。

输入n,x,y输出剩余的编号。

数据范围 1 < n <= 1000000, 1<=x,y<=1000000000。

#include<iostream>
using namespace std ;

struct Node {
int data ;
Node *prier ;
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-- ) {
s->prier = L ;
s->data = i ;
p = new Node ;
s->next = p ;
L = s ;
s = p ; // 此处不能delete p
}
L->next = h ;
h->prier = L ;
}

int Delete( LinkList &L , int x , int y ) { //递归删除第x个、第y个结点
for(int i = 2 ; i <= x ; i++ )
L = L->prier ;
L->prier->next = L->next ;
L->next->prier = L->prier ;
L = L->next ;
if(L->next == L->prier)
return L->next->data ;
for(int j = 2 ; j <= y ; j++ )
L = L->next ;
L->prier->next = L->next ;
L->next->prier = L->prier ;
L = L->prier ;
if(L->next == L->prier)
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 ;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: