当前位置: 代码迷 >> 综合 >> 关于小球移动题目的一点思考
  详细解决方案

关于小球移动题目的一点思考

热度:68   发布时间:2023-09-30 17:03:52.0

最近在网上看到一道题,是这样描述的:

Description
你有一些小球,从左到右依次编号为1,2,3,...,n. 你可以执行两种指令(1或者2)。其中, 1 X Y表示把小球X移动到小球Y的左边, 2 X Y表示把小球X移动到小球Y右边。 指令保证合法,即X不等于Y。

例如,初始状态1,2,3,4,5,6的小球执行1 1 4后,小球1被移动到小球4的左边,即2,3,1,4,5,6。如果再执行2 3 5,结点3将会移到5的右边,即2,1,4,5,3,6。 

Input
第一行为一个整数t(0<t<10),表示测试用例个数。
每个测试用例的第一行为两个整数n(1<n<=500000)和m(0<m<100000),n表示小球的个数,m为指令条数,以下m行每行为一条指令。

  
Output
为每个测试用例单独输出一行,从左到右输出最后序列,
每个数字后面跟一个空格。

  
Sample Input 

6 2 
1 1 4 
2 3 5 
5 1 
2 1 5  


Sample Output
2 1 4 5 3 6  
2 3 4 5 1

 

这道题目明显用链表简单,但是数组也是可以尝试的,但思路绝对要清晰。主要是判断原始球(X)和目的球(Y)的相对位置。

数组版本:

#include<stdio.h>void trans(int a[],int n,int dir,int xx,int yy){//小球移动函数int i,j,g,tmp,x,y;if(dir==1){for(i=0;i<n;i++){//判断移动的小球当前位置if(a[i]==xx) x=i;if(a[i]==yy) y=i;}if(x<y){//原始球在目的球的左方,移到左边tmp=a[x];for(j=x+1;j<=y-1;j++){a[j-1]=a[j];}a[y-1]=tmp;}else{//原始球在目的球的右方,移到左边tmp=a[x];for(j=x;j>y;j--){a[j]=a[j-1];}a[y]=tmp;} }else{for(i=0;i<n;i++){if(a[i]==xx) x=i;if(a[i]==yy) y=i;}if(x<y){//原始球在目的球的左方,移到右边tmp=a[x];for(j=x+1;j<=y;j++){a[j-1]=a[j];}a[y]=tmp;}else{//原始球在目的球的右方,移到右边tmp=a[x];for(j=x;j>y+1;j--){a[j]=a[j-1];}a[y+1]=tmp;}}
}int main(){int t,m,n,i,j,k,g,dir,xx,yy;while(scanf("%d",&t)!=EOF){for(i=0;i<t;i++){scanf("%d%d",&n,&m);int a[n]={0};for(k=0;k<n;k++){a[k]=k+1;}for(j=0;j<m;j++){scanf("%d%d%d",&dir,&xx,&yy);trans(a,n,dir,xx,yy);}for(g=0;g<n;g++){printf("%d ",a[g]);}printf("\n");}return 0;}
}

 

  相关解决方案