閱讀448 返回首頁    go 阿裏雲 go 技術社區[雲棲]


算法訓練-移動小球

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
Copy sample input to clipboard
2
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

 

 

本題訓練的是鏈表的思想,鏈表對於刪除與插入還有數字順序對調十分方便
(裏麵沒有用指針,隻用了結構體。比較好理解,指針目前不太會用)
AC代碼:

#include<stdio.h>
struct mode
{
  int L,R;
  int num;
}a[2000];//結構體,L,R分別是a[i]的左邊和右邊的數,a[i].num是a[i]本身的值 
void Move(int stap,int x,int y)
{
   if(stap==1)//模式1(將x移向y的左邊) 
   {
      a[a[x].R].L=a[x].L;//x的右邊的左邊等於x原來的左邊 
      a[a[x].L].R=a[x].R;//x的左邊的右邊等於x原來的右邊 
      a[x].L=a[y].L;//x的左邊等於y原來的左邊 
      a[a[y].L].R=a[x].num;//y原來的左邊的右邊變成x 
      a[x].R=a[y].num;//x的右邊變成y 
      a[y].L=a[x].num;//y的左邊變成x 
      return;
   }
   else
   if(stap==2)//模式2(將x移向y的右邊) 
   {
      a[a[x].R].L=a[x].L;//x的右邊的左邊等於x原來的左邊 
      a[a[x].L].R=a[x].R; //x左邊的右邊等於x原來的右邊 
      a[y].L=a[x].R;//y的左邊等於x原來的右邊 
      a[x].L=a[y].num;//x的左邊等於y 
      a[x].R=a[y].R;//x的右邊等於y原來的右邊 
      a[y].R=a[x].num;//y的右邊等於x 
      return;   
   }
   
}
int main()
{
    int i,j,n,sum,m,stap,x,y,k,first;
    scanf("%d",&n);
    while(n--)
    {
       scanf("%d%d",&sum,&m);
       for(i=1;i<=sum;i++)//初始化數組 
       {
           a[i].num=i;
           a[i].L=i-1;
           a[i].R=i+1;   
       }
       while(m--)
       {
          scanf("%d %d %d",&stap,&x,&y);
          Move(stap,x,y);//進行調換 
       }
       for(i=1;i<=sum;i++) 
       {
          if(a[i].L==0)//誰的左邊是0,誰第一個輸出 
          first=i;//標記第一個輸出的數 
       }
       k=0;
       while(k<=sum)
       {
           if(k==0)//第一次輸出 
           {
              //不輸出左邊的0(因為原來就沒有o) 
              printf("%d ",a[first].num);
              printf("%d ",a[first].R);
              k+=3;//下次的那個數沒有計算,這裏要加3而不是2 
              first=a[first].R;
           }
           else
           {
               printf("%d ",a[first].R);
               k++;//每輸出一個數k加一次,知道k滿足數組的長度退出 
               first=a[first].R;
           }
       }
       printf("\n");
    }
    return 0;
} 


代碼為原創,轉載請注明出處!

最後更新:2017-04-03 12:55:39

  上一篇:go Flume-ng的HdfsSink出現Lease mismatch錯誤
  下一篇:go C# 根據列名與列值設置當前行