夏令营骑手-链表
双向链表+来回查找
注意控制改变方向的条件
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef struct line L;
struct line
{
int num;
L *pnext;
L *plast;
};
int main()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
L *phead,*p;
phead=p=(L*)malloc(sizeof(L));
phead->plast=NULL;
p->num=1;
for(int i=2;i<=n;i++)//建立双向链表
{
p->pnext=(L*)malloc(sizeof(L));
p->pnext->plast=p;
p=p->pnext;
p->num=i;
}
p->pnext=NULL;
p=phead;
int t = 1;//标记数数的方向
int s = n;
while(s>1)
{
for(int i=1;i<m;i++)//因为本身要报一次数,所以是循环m-1次
{
if(t == 1)
{
p=p->pnext;
if(p->pnext==NULL)//如果正向数到头,就将标记变换,然后继续反向数
{
t=0;
continue;
}
}
else if(t == 0)
{
p=p->plast;
if(p->plast==NULL)//同理,反向数到头,改变标记正向数数
{
t=1;
continue;
}
}
}
if(p->plast!=NULL&&p->pnext!=NULL)//如果要出队的数前后还都有数存在,按照此方法
{
L *p1,*p2;//p1p2分别存储p前后的数据
p1=p->plast;
p2=p->pnext;
p1->pnext=p2;
p2->plast=p1;
if(t == 1)
p=p2;
if(t == 0)
p=p1;
if(p->pnext==NULL)
t=0;
if(p->plast==NULL)
t=1;
}
else
{
if(p->plast==NULL)
{
p->pnext->plast=NULL;
phead=p=p->pnext;
}
else if(p->pnext==NULL)//MD少写了个else,艹,这里如果不写else,最后剩两个数的时候就会走完上一循环直接因为满足此循环条件而走此循环,从而导致出错
{
p->plast->pnext=NULL;
p=p->plast;
}
}
s--;
}
printf("%d\n",p->num);
/*p=phead;
while(p->pnext!=NULL)//打印链表
{
printf("%d ",p->num);
p=p->pnext;
}
printf("%d\n",p->num);
while(p->plast!=NULL)
{
printf("%d ",p->num);
p=p->plast;
}
printf("%d\n",p->num);*/
return 0;
}