现在的位置: 首页 > 综合 > 正文

TopCoder SRM244 I 300 CircleDance – 构造

2012年11月27日 ⁄ 综合 ⁄ 共 1919字 ⁄ 字号 评论关闭

TopCoder SRM244 I 300 - CircleDance

题目大意:

已知n个人的身高(3<=n<=20),要求他们围成一个圈,使得相邻两人最大的身高之差最小。 

原文:

Given a group of dancers' heights, arrange a circle formation that minimizes the maximum height difference between each pair of neighboring dancers.
Write a class CircleDance with a method arrangeDancers that takes a int[], heights, and returns the maximum height difference between neighboring dancers.

解题思路:-------------------------------------------------------------------------------------------------------------

数据规模相当小,可以考虑使用枚举。但仔细考虑,可以有一种直接构造的方法得到最优方案。

当只有3个人的情况,围成一圈,最大的高度差为最高和最矮之差。因为他们无可避免地要站在相邻的位置。假设a<b<c,那么此时max=c-a。

若再插入一个d > a,b,c,那么d必然和2个人相邻。若把d安排和a相邻,显然是不合适的,因为这样必然会使max增加到max=d-a。所以,此时的d放在bc之间是最优选择,那么d两侧的最大高度差为d-b,即使d-b比原来的max更大也是无可奈何的。

同样地,若再插入一个e > a,b,c,d,那么e必然是放在当前最高的两人之间,即cd之间。依此类推。按照这样的规则,就可以依次插入一个更高的人,使他们构成一个环形,并且他们相邻两人的高度差的最大值是最小的。虽然没有严格证明(哪位朋友若有证明请吱一声^^)。

那么这个题就能解决了,先把人按照高度排序,编号奇数的由低到高站左边,偶数的由高到低站右边,然后首尾相接即可。

附代码:------------------------------------------------------------------------------------------

#include <iostream>
#include <vector>
#define N 25

using namespace std;

class CircleDance
{

public:

    int abs(int x)
    {
        return x>0?x:-x;
    }

    int Max(int a,int b)
    {
        return a>b?a:b;
    }

    int arrangeDancers(vector <int> h)
    {
        int i,j,k,n;
        int max,t,g[N];
       
        n=h.size();

        //sort
        for(i=0;i<n;i++)
        {
            k=i;
            for(j=i+1;j<n;j++) if(h[k]>h[j]) k=j;
            t=h[k];h[k]=h[i];h[i]=t;
        }

        //range
        k=0;
        for(i=0;i<n;i+=2) g[k++]=h[i];
        for(i=n%2?n-1:n-2;i>0;i-=2) g[k++]=h[i];

        //getmax
        max=abs(g[k-1]-g[0]);
        for(i=1;i<k;i++) max=Max(max,abs(g[i]-g[i-1]));
       
        return max;
    } 
};

int main() //test
{
    vector <int> h;
    int i,j,k,n;
    int max;
    CircleDance c;
   
    while(scanf("%d",&n),n)
    {
       
        for(i=0;i<n;i++){
            scanf("%d",&k);
            h.push_back(k);
        }
        max=c.arrangeDancers(h);
        h.clear();
        printf("%d/n",max);
    }
   
    return 0;
}

抱歉!评论已关闭.