题目链接:http://codeforces.com/gym/100283/problem/K
题解:
要使其相邻两项的差值之和最小,那么越靠中间,其数值越小。
那么剩下的问题就是如何放数字了。一开始的想法是从中间开始放,然后:左右左右……, 后来发现当为偶数个时,这种放法的字典序并非最小,应该右左右左地放。所以从中间向两边扩散的放法需要分奇偶讨论(不太好写)。那有没有其他放法不用分类讨论,且一步过的?有的,就是从两边开始,往中间靠近,即右左右左一直放到中间没有剩余位置。这种放法保证了字典序大的一定被放在后面的位置。
两道与此题思想相近的题:
http://blog.youkuaiyun.com/dolfamingo/article/details/54999938
http://blog.youkuaiyun.com/dolfamingo/article/details/62887448
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define LOCAL
#define eps 0.0000001
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int maxn = 100+10;
const int mod = 1000000007;
int a[maxn], ans[maxn];
int main()
{
#ifdef LOCAL
freopen("cubes.in", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif // LOCAL
int T;
int cnt = 1;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
for(int i = 1; i<=n; i++)
scanf("%d", &a[i]);
sort(a+1, a+1+n);
int l = 1, r = n, now = n;
while(now)
{
ans[r--] = a[now--];
if(now)
ans[l++] = a[now--];
}
printf("Case %d:\n", cnt++);
for(int i = 1; i<=n; i++)
{
printf("%d", ans[i]);
if(i<n)
putchar(' ');
}
printf("\n");
}
return 0;
}