UVa 10057 - A mid-summer night's dream
题目大意:给n个数,找一个数A使得A与这n个数的差的绝对值最小。输出A最小的可能值,n个数中满足A的性质的数的个数以及满足A性质的不同的数的个数(不必从这n个数中挑选)。
看见绝对值就想到了数轴上点之间的距离,从寻找中位数入手。本来是打算把所有数都保存然后排序的,忽然就看到了题目上所有数都小于65536,就想到用计数排序,然后就敲啊敲,提交!正为节省了点空间而小小自得呢,就WA了... -_-|| ,再看看感觉也没什么问题,只好搜代码了,看到别人都是直接存的数然后进行处理,就想哪出问题了,看到那些重复的数就明白了,还以为用计数(开始想用游程编码来着)方法处理重复的数不错了,其实是我错了,把所有的相同的数合并时涉及到一个类似“权重”的问题,比如5个数,1,1,1,1,4,如果简单的合并成1,4就会出问题了。计数+权重的方法没什么思路,就算有让我现在去想也会变成无比麻烦的东西,还是先老老实实按套路来吧。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define MAXN 1000000+10 6 7 int num[MAXN]; 8 9 int main() 10 { 11 #ifdef LOCAL 12 freopen("in", "r", stdin); 13 #endif 14 int n; 15 while (scanf("%d", &n) != EOF) 16 { 17 for (int i = 0; i < n; i++) 18 scanf("%d", &num[i]); 19 sort(num, num+n); 20 int left = (n-1)/2, right; 21 if (n % 2) right = left; 22 else right = left + 1; 23 int cnt = 0; 24 for (int i = 0; i < n; i++) 25 { 26 if (num[i] >= num[left] && num[i] <= num[right]) cnt++; 27 if (num[i] > num[right]) break; 28 } 29 printf("%d %d %d\n", num[left], cnt, num[right]-num[left]+1); 30 } 31 return 0; 32 }