这道题做了一天了,开始用单向链表做,但是发现用了空表头就在中间处理的时候出现了问题,如果是没形成循环,就没办法记录两个指针;并且多次访问会超时,所以下午用了双向指针加结构体数组来做,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;elsereturn 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;
}