CODE[VS] 2221 搬雕像 ——2011年台湾高级中学咨询学科能力竞赛

题目描述 Description

王先生是一位收藏家,他收集了非常多有名的雕像。某天,为了美观,他想要将收藏台上的雕像按照某种方式重新摆放,由于雕像都有一定的重量,所以他决定雇用一位年轻人,小明,來帮忙搬雕像。 
王先生收藏的雕像目前是以随机的方式放在收藏台上,收藏台的位置由左至右成一列排开,编号依序为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

 

 

 

 

 

posted @ 2018-06-17 08:32  孟东行#  阅读(368)  评论(0编辑  收藏  举报