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
根据前面的推论,我们知道我们总是将当前的数插在整个序列的中间位置,因为上个数也是在中间,而且是奇偶交替的。故而可先生成这个置换,然后将原序列排序后,进行置换,然后返回结果。
代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#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; } };