SICILY 1934 移动小球
看到链表于是顺便尝试了一下。。好吧,本题不难,但是有一些很好的方法确实可以从中体会到。
首先,链表的使用上,并不是非得用结构实现的,可以用多个数组来代替实现链表的功能。不然,你的代码看起来会是这样:
if(op==1){
ball[p[ad1]].left->right=ball[p[ad1]].right;
ball[p[ad1]].right->left=ball[p[ad1]].left;
ball[p[ad1]].left=ball[p[ad2]].left;
ball[p[ad1]].right=&ball[p[ad2]];
ball[p[ad2]].left->right=&ball[p[ad1]];
ball[p[ad2]].left=&ball[p[ad1]];
}else if(op==2){
ball[p[ad1]].left->right=ball[p[ad1]].right;
ball[p[ad1]].right->left=ball[p[ad1]].left;
ball[p[ad1]].right=ball[p[ad2]].right;
ball[p[ad1]].left=&ball[p[ad2]];
ball[p[ad2]].right->left=&ball[p[ad1]];
ball[p[ad2]].right=&ball[p[ad1]];
}
好吧,对结构指针的运用不是很熟悉,所以看起来很繁琐,但是一旦用了结构实现的话看起来一定不会很简洁。
其次,链表并不是只包含一个指针的,在这道题上面,双向链表的使用可以大大降低本题的复杂度。
最后,再用链表做合并操作的时候,使用一个函数确实非常简洁。
编写连接链表函数link
void link(int x,int y)
{
right[x]=y;
left[y]=x;
}
以后就可以用link( left [x] , y ); 等类似这样的方式调用了。
#include<stdio.h>
#define MAXN 500000
int left[MAXN+10],right[MAXN+10];
void link(int x,int y)
{
right[x]=y;
left[y]=x;
}
int main()
{
int i,j,op,ad1,ad2,n,m,dn,first;
/*freopen("ball.in","r",stdin);*/
scanf("%d",&dn);
for(i=1;i<=dn;i++){
scanf("%d%d\n",&n,&m);
for(j=1;j<=n;j++){
left[j]=j-1;
right[j]=j+1;
}
for(j=1;j<=m;j++){
scanf("%d%d%d",&op,&ad1,&ad2);
link(left[ad1],right[ad1]);
if(op==1){
link(left[ad2],ad1);
link(ad1,ad2);
}else if(op==2){
link(ad1,right[ad2]);
link(ad2,ad1);
}
if(left[1]!=first) first=left[1];
}
first=0;
for(j=1;j<=n;j++){
first=right[first];
printf("%d ",first);
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号