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;
}




 

posted @ 2013-07-01 20:57  KaitoHH  阅读(76)  评论(0)    收藏  举报