放题。
约瑟夫环
题目描述
N个人坐成一个圆环(编号为1 - N),从第S个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2,S = 1。2号先出列,然后是1号,最后剩下的是3号。
测试数据有多组,每组包括3个数N、K、S,表示有N个人,从编号为S的人开始,数到K出列。(2 <= N <= 10^6,1 <= K <= 10, 1 <= S <= N)
输入
测试数据有多组
每组包括3个数N、K、S,表示有N个人,从第S个人开始,数到K出列。(2 <= N <= 10^3,10^3 < K <= 10^9, 1 <= S <= N)
输出
出列的人的编号
样例输入
13 3 1
3 2 1
样例输出
3 6 9 12 2 7 11 4 10 5 1 8 13
2 1 3
emmmm这道题...纯手写链表...
#include <cstdio>
using namespace std;
struct node{
int num;
node *next;
};
int n,k,m;
void CreateList(node *&h)
{
node *p,*tail;
int i;
for(i=1;i<=n;i++){
p=new node;
p->num=i;
p->next=NULL;
if(h==NULL)
h=p;
else
tail->next=p;
tail=p;
}
p->next=h;
}
void Delete(node *head)
{
int l=n;
node *play=head,*temp;
temp=play;
while(play->num!=k)
play=play->next;
while(temp->next!=play)
temp=temp->next;
while(play->next!=play){
int t=m;
if(m>l){ //这一步提高效率,将O(m*n)变成O(n)
if(m%l==0)
t=l;
else
t=m%l;
}
for(int i=1;i<t;i++){
temp=temp->next;
play=play->next;
}
printf("%d ",play->num);
l--;
temp->next=play->next;
delete(play);
play=temp->next;
}
printf("%d \n",play->num);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
node *head=NULL;
CreateList(head);//创建
Delete(head);
}
return 0;
}