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; }