Topcoder SRM 662 DIV1

FoxesOfTheRoundTable

题意:

给你一个序列,让你生成一个排列,并且这个排列是循环的。使得任意两个相邻数的差的最大值尽量小。

题解:

先排个序,然后从小到大逐个插入。这时容易发现,若要得到最优的策略,只能将现在的这个数插在当前排列中最大的那个数的旁边,这是因为,要插入的这个数是大于当前排列中的任何一个数,故而插入只会产生一个更大的差距,为了使这个差距尽量小,就不得不在最大的数旁边插入。

假如现在的序列就是0 1 2 3 4 5

首先前三个数是没有影响的:0 1 2

插入3:0 1 3 2

插入4:0 1 3 4 2

插入5:0 1 3 5 4 2

根据前面的推论,我们知道我们总是将当前的数插在整个序列的中间位置,因为上个数也是在中间,而且是奇偶交替的。故而可先生成这个置换,然后将原序列排序后,进行置换,然后返回结果。

代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#define MAX_N 55
using namespace std;

int n;

vector<int> res;

struct node{
public:
    int val,pos;
};

bool cmp(node a,node b){
    return a.val<b.val;
}

node x[MAX_N];

class FoxesOfTheRoundTable {
public:
    vector<int> minimalDifference(vector<int> h) {
        n = h.size();
        res.push_back(0);
        if (n == 1)return res;
        res.push_back(1);
        if (n == 2)return res;
        res.push_back(2);
        if (n == 3)return res;
        res.clear();
        for (int i = 0; i < n; i++)x[i].val = h[i], x[i].pos = i;
        sort(x, x + n, cmp);
        res.push_back(x[0].pos);
        for (int i = 1; i < n; i += 2)res.push_back(x[i].pos);
        for (int i = ((n - 1) >> 1) << 1; i > 0; i -= 2)res.push_back(x[i].pos);
        return res;
    }
};
View Code
原文地址:https://www.cnblogs.com/HarryGuo2012/p/4834912.html