Gym - 100283K K. Cubes Shuffling —— 贪心

题目链接:http://codeforces.com/gym/100283/problem/K


题解:

要使其相邻两项的差值之和最小,那么越靠中间,其数值越小。

那么剩下的问题就是如何放数字了。一开始的想法是从中间开始放,然后:左右左右……, 后来发现当为偶数个时,这种放法的字典序并非最小,应该右左右左地放。所以从中间向两边扩散的放法需要分奇偶讨论(不太好写)。那有没有其他放法不用分类讨论,且一步过的?有的,就是从两边开始,往中间靠近,即右左右左一直放到中间没有剩余位置。这种放法保证了字典序大的一定被放在后面的位置。

两道与此题思想相近的题:

http://blog.csdn.net/dolfamingo/article/details/54999938

http://blog.csdn.net/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;
}


posted on 2017-04-20 23:57  h_z_cong  阅读(253)  评论(0编辑  收藏  举报

导航