我们首先将所有电池排序,那么我们可以找到一组最优方案,使得一台机器的能量之差是相邻两电池的能量之差。
然后我们就二分这个答案,从前往后贪心地选这个数对,然后看是否所有的数对都是满足条件的。
假设这个数对是 i - 1, i,并且是第 j 个数对,那么我们称满足条件为:
2nk - i + 2 >= 2k(n - j + 1)
意思就是能拿出足够多的电池来组成机器人。
然后注意特判:如果不能选出足够多的数对就返回 false,我在这里 WA 到死。。。
毕竟 Gromah 太弱,只会做水题。
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 #define N 1000000 + 5 8 9 int n, k, size, Max, A[N]; 10 11 inline int getint() 12 { 13 char ch = ' '; 14 for (; ch > '9' || ch < '0'; ch = getchar()) ; 15 int res = ch - '0'; 16 for (ch = getchar(); ch >= '0' && ch <= '9'; ch = getchar()) 17 res = (res << 3) + (res << 1) + ch - '0'; 18 return res; 19 } 20 21 inline bool Judge(int m) 22 { 23 int cnt = n; 24 for (int i = 2; cnt && i <= size; i ++) 25 if (A[i] - A[i - 1] <= m) 26 { 27 if (size - i + 2 < 2 * cnt * k) return 0; 28 cnt --, i ++; 29 } 30 return !cnt; 31 } 32 33 int main() 34 { 35 #ifndef ONLINE_JUDGE 36 freopen("3969.in", "r", stdin); 37 freopen("3969.out", "w", stdout); 38 #endif 39 40 n = getint(), k = getint(); 41 size = (n * k) << 1; 42 for (int i = 1; i <= size; i ++) 43 { 44 A[i] = getint(); 45 Max = max(Max, A[i]); 46 } 47 sort(A + 1, A + size + 1); 48 int l = A[2] - A[1], r = Max; 49 while (l < r) 50 { 51 int mid = (l + r) >> 1; 52 if (Judge(mid)) r = mid; 53 else l = mid + 1; 54 } 55 printf("%d ", l); 56 57 #ifndef ONLINE_JUDGE 58 fclose(stdin); 59 fclose(stdout); 60 #endif 61 return 0; 62 }