这道题做了一天了,开始用单向链表做,但是发现用了空表头就在中间处理的时候出现了问题,如果是没形成循环,就没办法记录两个指针;并且多次访问会超时,所以下午用了双向指针加结构体数组来做,ball[i]代表第i个球(类似)节点,然后前后两个指针形成环。在取出小球节点时只处理了一侧的指针,导致浪费了一下午去挑错误。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 10005
struct node
{
node *left;
node *right;
int num; //记录小球球号
} ball[Max];
void initial (int n) //初始化球环
{
for(int i=1; i<=n; i++)
{
ball[i].num=i;
if(i<n)
{
ball[i].right=&ball[i+1];
}
else //处理尾部,与头衔接
{
ball[i].right=&ball[1];
}
if(i==1) //处理头部,与尾衔接
{
ball[i].left=&ball[n];
}
else
{
ball[i].left=&ball[i-1];
}
}
}
void movenode(char a,int x,int y)
{
struct node *p,*q;
p=&ball[x],q=&ball[y];
p->left->right=p->right; //取出小球的位置,前后小球指针互指
p->right->left=p->left;
if(a=='A')
{
q->left->right=p; //在插入位置处理好插入小球与前后小球连接
p->left=q->left;
p->right=q;
q->left=p;
}
else if(a=='B')
{
q->right->left=p;
p->right=q->right;
p->left=q;
q->right=p;
}
}
int findnode(int x,int y) //找出目标小球的左右小球编号
{
if(x)
return ball[y].right->num;
else
return ball[y].left->num;
}
int main()
{
//freopen("I:aa.txt","r",stdin);
//freopen("F:a.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
initial(n);
char a;
int x,y;
for(int i=0; i<m; i++)
{
getchar();
scanf("%c%d%d",&a,&x,&y);
if(a=='A'||a=='B')
{
movenode(a,x,y);
}
else if(a=='Q')
{
int ans=findnode(x,y);
printf("%d\n",ans);
}
}
}
return 0;
}