CODE[VS] 2221 搬雕像 ——2011年臺灣高級中學咨詢學科能力競賽
王先生是一位收藏家,他收集了非常多有名的雕像。某天,為了美觀,他想要將收藏臺上的雕像按照某種方式重新擺放,由於雕像都有一定的重量,所以他決定雇用一位年輕人,小明,來幫忙搬雕像。
王先生收藏的雕像目前是以隨機的方式放在收藏臺上,收藏臺的位置由左至右成一列排開,編號依序為1, 2,..., n ,每個收藏臺上放置一個雕像,而收藏臺i (1 ≤ i ≤ n) 上目前放的雕像編號為 Si,其高度為 hi 公分,重量為 wi 公斤。王先生要求小明依照下列方式去重新擺放雕像:
(a) 搬動過程中,一次只能搬一個雕像,而每個收藏臺可暫時放置 0個、1 個、或多個雕像。
(b) 完成重新擺放之後需符合下列條件:
- 每個收藏臺上放置一個雕像。
- 雕像必須根據高度,由低至高從最左邊的收藏臺開始依序放置。
- 若任二雕像的高度相同時,則重量輕的雕像放置在左邊。
- 若任二雕像高度和重量都相同時,則依照原先雕像的左右相對順序來放置,也就是說原先在左邊的雕像必須放置在左邊。
為了節省搬運的距離,小明希望你替他寫出一個程序,根據上述方式將雕像重新擺放在收藏臺上且搬動的總距離為最短。本題假設任二相鄰收藏臺的距離為1 公尺。
以下為一個範例,假設有 5 個收藏臺,雕像 Si (1 ≤ i ≤ 5) 的高度和重量以(hi, wi)表示,並依序為(5,20) ,(10,25) ,(78,40) ,(25,25) ,(5,15) 。一種搬動方式如圖(a)所示,搬動的總距離為 12公尺,而另一種搬動方式如圖(b)所示,搬動的總距離為8 公尺,是所有符合搬動方式中的最短距離。
輸入描述 Input Description
第一行有一個整數n,1≤ n≤ 10000,代表收藏臺的個數。接下來的n 行,每行有兩個整數以空白隔開,其中第 i 行(1 ≤i ≤ n) 為目前放在收藏臺i 上雕像Si 的高度hi( 單位為公分) 和重量wi( 單位為公斤) ,hi 和wi 都介於1 和65536 之間
輸出描述 Output Description輸出一個整數,代表搬動雕像所需的最短總距離( 單位為公尺) 。
樣例輸入 Sample Input
樣例1:
5
5 20
10 25
78 40
25 25
5 15
樣例2:
8
5 15
3 5
9 13
13 20
24 30
40 50
9 12
5 15
樣例輸出 Sample Output樣例1:
8
樣例2:
18
數據範圍及提示 Data Size & Hint
1≤ n≤ 10000
hi 和wi 都介於1 和65536 之間
TW一百學年度全國高級中學咨詢學科能力競賽決賽1
今天蒽的托人給我送來水果,
還是很開心的。
告別昨天,迷茫雲煙,,
把不開心的都忘掉吧。
這個題我一開始覺得肯定要用冒泡啊什麽的
一步一步來模擬過程,
在模擬的過程中加上距離,
不能用快排,因為這樣體現不出過程,
就沒法求距離了。(都怪例子坑了我)
事實證明我錯了。
模擬過程相當復雜且不易想出比較好的思路。
當然應該也可以,
但正解應該是用快排,
那麽如何求最短移動距離呢?
直接從結果入手來求呀!
然後可以寫出排好序後的樣例,
可以多試幾組樣例,
發現最終求得的最短移動距離恰等於移動前後各位置序號差的和。
(no代表序號)
所以就可以直接用快排,最後算結果就好了。
ac代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 8 int n,b[10002],t; 9 10 struct node{ 11 int h,w,no; 12 }a[10002]; 13 14 bool cmp(node x,node y) 15 { 16 if(x.h >y.h ) return false; 17 if(x.h <y.h ) return true; 18 if(x.w >y.w ) return false; 19 if(x.w <y.w ) return true; 20 return x.no <y.no ; 21 } 22 23 int abss(int x,int y) 24 { 25 if(x<y) return y-x; 26 else return x-y; 27 } 28 29 int main() 30 { 31 scanf("%d",&n); 32 for(int i=1;i<=n;++i) 33 { 34 scanf("%d%d",&a[i].h,&a[i].w); 35 a[i].no =i; 36 b[i]=i; 37 } 38 sort(a+1,a+n+1,cmp); 39 for(int i=1;i<=n;++i) 40 t+=abss(a[i].no ,b[i]); 41 printf("%d",t); 42 return 0; 43 }
如果你不開心,那我就把右邊這個帥傻子分享給你吧,
你看,他這麽好看,跟個zz一樣看著你,你還傷心嗎?
真的!這照片盯上他五秒鐘就想笑了。
一切都會過去的。
時間時間會給你答案2333
CODE[VS] 2221 搬雕像 ——2011年臺灣高級中學咨詢學科能力競賽