日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

移动小球

發布時間:2025/6/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 移动小球 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.




移動小球

時間限制(普通/Java)?:?1000 MS/?3000 MS?? ? ? ???運行內存限制 : 65536 KByte
總提交 : 995 ? ? ? ?? ? 測試通過 : 131?

題目描述

你有一些小球,從左到右依次編號為1,2,3,…,n,如下圖所示:

你可以執行兩種指令。其中A X Y表示把小球X移動到小球Y左邊,B X Y表示把小球X移動到小球Y右邊。指令保證合法,即X不等于Y。
例如,在初始狀態下執行A 1 4后,小球1被移動到小球4的左邊,如下圖所示:

如果再執行B 3 5,結點3將會移到5的右邊,如下圖所示:



輸入

輸入小球個數n。指令條數m和m條指令,注意,1≤n≤500000,0≤m≤100000。

輸出

從左到右輸出最后的小球序列。

樣例輸入

6?2
A?1?4
B?3?5

樣例輸出

2?1?4?5?3?6





在多數情況下,線性表都用它的順序存儲結構——數組很輕松實現,但對有些問題有時用它的鏈式存儲結構——鏈表更好。

移動小球。

你有一些小球,從左到右依次編號為1,2,3,…,n,

可以執行兩種指令。其中,AX Y表法把小球X移動到小球Y左邊,B X Y表示把小球X移動到小球Y右邊。指令保證合法,即X不等于Y。

例如,在初始狀態下執行A1 4后,小球被移動小球4的左邊。

如果再執行B 3 5,結點3將會移到5的右邊。

輸入小球個數n,指令條數m和n條指令,從左到右輸出最后的序列。注意,n可能高達500000,而m可能高達100000。

樣例輸入:

6?????2

A? 1? 4

B? 3? 5

樣例輸出:

2 1 4 5 3 6

【分析】

各個小球在邏輯上是相鄰的,因此可考慮把它們放在一個數組A中,所以完整的程序如下:

[cpp]?view plaincopyprint?
  • #include?<stdio.h>??
  • const?int?MAXN?=?1000;??
  • int?n,?A[MAXN];??
  • int?find(int?X)??
  • {??
  • ????for(int?i?=?1;?i?<=?n;?i++)??
  • ????????if(A[i]?==?X)?return?i;??
  • ????return?0;??
  • }??
  • void?shift_circular_left(int?a,?int?b)??
  • {??
  • ????int?t?=?A[a];??
  • ????for(int?i?=?a;?i?<?b;?i++)??
  • ????{??
  • ????????A[i]?=?A[i+1];??
  • ????}??
  • ????A[b]?=?t;??
  • }??
  • void?shift_circular_right(int?a,?int?b)??
  • {??
  • ????int?t?=?A[b];??
  • ????for(int?i?=?b;?i?>?a;?i--)??
  • ????{??
  • ????????A[i]?=?A[i-1];??
  • ????}??
  • ????A[a]?=?t;??
  • }??
  • int?main()??
  • {??
  • ????int?m,?X,?Y,?p,?q;??
  • ????char?type[9];??
  • ????scanf("%d%d",?&n,?&m);??
  • ????for(int?i?=?1;?i?<=?n;?i++)???//初始化數組??
  • ????????A[i]?=?i;??
  • ????for(int?i?=?0;?i?<?m;?i++)??
  • ????{??
  • ????????scanf("%s%d%d",?type,?&X,?&Y);??
  • ????????p?=?find(X);????????????????//查找X和Y在數組中的位置??
  • ????????q?=?find(Y);??
  • ????????if(type[0]?==?'A')??
  • ????????{??
  • ????????????if(q?>?p)??
  • ????????????????shift_circular_left(p,?q-1);??//A[p]到A[q-1]往左循環移動??
  • ????????????else?shift_circular_right(q,?p);????????//A[q]到A[p]往右循環移動??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????if(q?>?p)??
  • ????????????????shift_circular_left(p,?q);???//A[p]到A[q]往左循環移動??
  • ????????????else?shift_circular_right(q+1,?p);?????//A[q+1]到A[p]往右循環移動??
  • ????????}??
  • ????}??
  • ????for(int?i?=?1;?i?<=?n;?i++)??
  • ????????printf("%d?",?A[i]);??
  • ????printf("\n");??
  • ????return?0;??
  • }??

  • ?

    對于上面的程序,當數據量很大時,代碼是否會超時。一般來說,可以用兩種方法判斷:測試和分析。

    計時測試的方法在前面已講過,它的優點是原理簡單、可操作性強,缺點在于必須事先程序寫好——包括主程序和測試數據生成器。如果算法非常復雜,這是相當花時間的。

    另一種方法是寫程序之前進行算法分析,估算時間效率,這種方法在第8章會詳細分析。不過現在可以直觀分析一下:如果反復執行B 1 n和A 1 2,每次都移動幾乎所有元素。元素個數和指令條數都那么大,移動總次數將是相當可觀的。

    2、鏈式結構

    [cpp]?view plaincopyprint?
  • #include?<stdio.h>??
  • #include<string.h>??
  • const?int?MAXN?=?1000;??
  • int?n,?left[MAXN],?right[MAXN];??
  • /*利用left數組和right數組*/??
  • /*分別代表元素X的左右數字*/??
  • void?link(int?X,?int?Y)??
  • {??
  • ????right[X]?=?Y;??
  • ????left[Y]?=?X;??
  • }??
  • //link函數實現了兩元素的銜接??
  • int?main()??
  • {??
  • ????int?m,?X,?Y;??
  • ????char?type[9];??
  • ????scanf("%d%d",?&n,?&m);??
  • ????memset(left,0,sizeof(left));??
  • ????memset(right,0,sizeof(right));??
  • ????for(int?i?=?0;?i?<=?n;?i++)??
  • ????{??
  • ????????left[i]?=?i-1;??
  • ????????right[i]?=?i+1;??
  • ????}??
  • ????/*初始化:用left和right數組標記好元素X左右元素*/??
  • ????for(int?i?=?0;?i?<?m;?i++)??
  • ????{??
  • ????????scanf("%s%d%d",type,?&X,?&Y);??
  • ????????link(left[X],?right[X]);//第一步:將X取出來??
  • ????????if(type[0]?==?'A')??
  • ????????{??
  • ????????????link(left[Y],?X);?//這一行和下一行不能搞反??
  • ????????????link(X,?Y);??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????link(X,?right[Y]);???//這一行和下一行不能搞反??
  • ????????????link(Y,?X);??
  • ????????}??
  • ????}??
  • ????for(int?w?=?right[0];?w?!=?n+1;?w?=?right[w])//right[w]:w后面的元素??
  • ????????//int?a?=?right[0];??
  • ????????printf("%d?",?w);??
  • ????printf("\n");??
  • ????return?0;??
  • }??

  • 總結

    以上是生活随笔為你收集整理的移动小球的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。