原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf
题目翻译:
问题描述
有n个机器,每个机器有2个芯片,每个芯片可以放k个电池。
每个芯片能量是k个电池的能量的最小值。
两个芯片的能量之差越小,这个机器就工作的越好。
现在有2nk个电池,已知它们的能量,我们要把它们放在n个机器上的芯片上,
使得所有机器的能量之差的最大值最小。
输入格式
第一行,两个正整数,n和k。
第二行,2nk个整数,表示每个电池的能量。
输出格式
一行一个整数,表示所有机器的能量之差的最大值最小是多少。
样例输入
2 3
1 2 3 4 5 6 7 8 9 10 11 12
样例输出
1
样例输入
2 2
3 1 3 3 3 3 3 3
样例输出
2
数据规模和约定
2nk <= 10^6, 1 <= pi <= 10^9。
题目大意:题目翻译已经足够简略了,不需要再简化了。。
思路分析:2013年World Finals难得的水题啊!首先每台机器分配2k个电池,那它的能量之差最小值一定是最小的两个电池的差。同样的,我们可以对所有电池的能量进行排序,每一台机器的能量之差一定是排序后相邻两节电池的能量之差。看到“最大值最小”的想法一定是二分答案p,如果对于所有\(0\le i \le n\)在排序后的序列中的前\(2Ki\)个电池中,都存在i对电池的能量之差小于等于p,则这个p是合要求的
算法流程:
二分答案p然后贪心判定即可
参考代码:
1 //date 20140122 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int maxnk = 1000006; 9 10 inline int getint() 11 { 12 int ans(0); char w = getchar(); 13 while(‘0‘ > w || w > ‘9‘)w = getchar(); 14 while(‘0‘ <= w && w <= ‘9‘) 15 { 16 ans = ans * 10 + w - ‘0‘; 17 w = getchar(); 18 } 19 return ans; 20 } 21 22 inline int max(int a, int b){return a > b ? a : b;} 23 inline int min(int a, int b){return a < b ? a : b;} 24 25 int n, k, nk; 26 int chips[maxnk]; 27 28 inline bool check(int w) 29 { 30 for(int p = 1, q = 0; q < n; ++p) 31 { 32 if(p - 1 > q * 2 * k)return false; 33 if(chips[p + 1] - chips[p] <= w)++p, ++q; 34 } 35 return true; 36 } 37 38 inline int solve(int l, int r) 39 { 40 int mid; 41 while(l < r) 42 { 43 mid = (l + r) >> 1; 44 if(check(mid))r = mid; 45 else l = mid + 1;; 46 } 47 return l; 48 } 49 50 int main() 51 { 52 freopen("low.in", "r", stdin); 53 freopen("low.out", "w", stdout); 54 55 while(scanf("%d%d", &n, &k) != EOF) 56 { 57 nk = 2 * n * k; int Max = 0; 58 for(int i = 1; i <= nk; ++i){chips[i] = getint(); Max = max(Max, chips[i]);} 59 sort(chips + 1, chips + nk + 1); 60 int ans = solve(0, Max); 61 printf("%d\n", ans); 62 } 63 64 return 0; 65 }
没什么需要注意的地方。。