Codeforces Round#251(Div 2)D Devu and his Brother
——你以为你以为的,就是你以为的?
——有时候还真是
题目链接:http://codeforces.com/contest/439/problem/D
题意大概就是要求第一个数组的最小值要不小于第二个数组的最大值,你所能做的就是对数组中的某一个数进行+1/-1的操作。最后问操作次数最少需要多少次。
起初这题我看着样例就开始瞎YY了,YY思路如图= =|||
看似有那么一丁点道理,但是其实是无法这么找到的,很快就自己找到了反例。。
不过之所以说是有那么一点道理是因为样例中的边缘数正好是它的平衡点,所谓平衡点就是将第一个数组里的数提升到某一个数a之上,把第二个数组的所有数降到数a之下。这就好比将一个天平平衡了,也就是最优解了。
可随之而来的问题也就很明了了,如何找到哪个平衡数呢?
我们不妨先把两个数组里的数存到同一个数组里,然后升序排序,这样我们就得到了一条线性的数列,那么既然是n+m个数里前m个要比后n个小,也就很自然的能找到平衡点为数列当中的第m或者第m+1个数了。
#include<cstdio> #include<algorithm> #define MAX(a,b) ((a>b)?(a):(b)) using namespace std; int a[1000010],b[1000010],c[2000020]; int main(){ int n,m; long long ans= 0LL; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]),c[i]=a[i]; for(int i=0;i<m;i++) scanf("%d",&b[i]),c[n+i]=b[i]; sort(c,c+m+n); int temp=c[m]; for(int i=0;i<n;i++) ans+=MAX(0,(temp-a[i])); for(int i=0;i<m;i++) ans+=MAX(0,(b[i]-temp)); printf("%I64d\n",ans); return 0; }