• 第二届河南省大学生程序设计竞赛 试题4 壮观的瓷器广场


    【试题四】
    壮观的瓷器广场
    【问题描述】
    最近,某瓷都为了体现“千年瓷都” 的风貌,将要建立一个壮观的瓷器广场迎接来自各国的宾客。,顾问Dr.Kong提出了一项建议:在巨大的广场南面展示N件高度不等的瓷器灯柱。夜间,这些瓷器灯柱逐一闪亮,由低至高,如此场景必将十分的绚丽夺目。
    然而,在瓷器灯柱运来安放后,Dr.Kong才发现粗心的工人并没有按照从低到高的顺序安放瓷器灯柱。由于瓷器灯柱已经竖立起来,不可能全部推倒重新安放,人力又搬不动。因此,Dr.Kong只能借助巨型吊车每次将两个瓷器灯柱的位置小心翼翼地进行交换。 例如,有3个瓷器灯柱初始时高度顺序是:3 1 2。可以先用吊车交换后两个灯柱的位置,得到3 2 1,再交换第一和第三个灯柱,得到最终序列1 2 3。 毕竟,用吊车交换灯柱位置可不是一件容易的事情,灯柱越高其重量越大,交换的难度也就越高。Dr.Kong估算出,每一次交换的难度等于交换的两个灯柱的高度的和。而整个交换方案的难度等于每次交换难度的总和。 例如先前的交换方案。原先3 1 2,交换后两个(难度为1+2=3),得到3 2 1,再交换第一和第三个(难度为3+1 = 4),得到1 2 3。因此,该方案的难度为3+4 =7。 为了使交换工作尽快完成,难度最低的交换方案自然是首选了。Dr.Kong虽然知道一些选择,冒泡,归并,快速甚至堆排序等。然而,在该问题面前,这些方法看起来似乎毫无用武之地!你有何办法?
    【标准输入】
    第一行: M 表示以下有M组测试数据(0<M<=8)
    接下来每组有两行数据
    头一行: N (表示瓷器灯柱的数目1 ≤ N ≤ 100 ) 下一行: H1 H2 ….Hn (表示依次安放灯柱的高度, 1≤Hi≤ 1000,)
    【标准输出】
    输出有M行,第i行为仅包含一个整数, 为第i组测试数据可得到的交换方案的最低难度值。
    【 样 例 】
    标准输入
    标准输出
    2 3
    3 1 2
    4 30 40 10 23
    7 103

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 int l[105],al[105];
     6 int hash[1005];
     7 bool vis[105];
     8 int main(){
     9     int M,N;
    10     int rmin=1000;
    11     int i,length,ans;
    12     scanf("%d",&M);
    13     while(M--){
    14         scanf("%d",&N);
    15         for(ans=i=0;i<N;i++){
    16             scanf("%d",&l[i]);
    17             al[i]=l[i];
    18             hash[l[i]]=i;
    19             if(rmin>l[i]) rmin=l[i];
    20         }
    21         sort(al,al+N);
    22         for(i=0;i<N;i++)
    23             printf("%d ",al[i]);
    24         puts("");
    25         memset(vis,0,sizeof(vis));
    26         length=N;
    27         while(length>0){
    28             int i=0,len=0;
    29             int min=1000;
    30             while(vis[i]) i++;
    31             int begin=i;
    32             int sum1,sum2,sum=0;
    33             while(1){
    34                 len++;
    35                 if(min>l[i]) min=l[i];
    36                 vis[i]=1;
    37                 sum+=l[i];
    38                 i=hash[al[i]];
    39                 if(i==begin) break;
    40             }
    41             length-=len;
    42             if(len==1) continue;
    43             sum1=sum+(len-2)*min;
    44             sum2=sum+min+(len+1)*rmin;
    45             ans+=(sum1>sum2 ? sum2 : sum1);
    46         }
    47         printf("%d\n",ans);
    48     }
    49     while(1);
    50     return 0;
    51 }

    做这道题复习了以前学的置换群:这道题和POJ3270一样!参见POJ3270

  • 相关阅读:
    Web应用指纹识别
    同步I/O 和 异步I/O
    怎样找出自己定义标签的java类
    Android多线程文件下载器
    cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&amp;同一时候带着刚体
    记C++课程设计--学生信息管理系统
    iOS开发--从TQRichTextViewDemo中学会分析project
    九度oj题目&amp;吉大考研10年机试题全解
    setOnFocusChangeListener的使用
    查看网络port占用
  • 原文地址:https://www.cnblogs.com/shihuajie/p/3043542.html
Copyright © 2020-2023  润新知