Time limit 2000 ms Memory limit 262144 kB
题目链接https://codeforces.com/problemset/problem/493/C
Vasya follows a basketball game and marks the distances from which each team makes a throw. He knows that each successful throw has value of either 2 or 3 points. A throw is worth 2 points if the distance it was made from doesn’t exceed some value of d meters, and a throw is worth 3 points if the distance is larger than d meters, where d is some non-negative integer.
Vasya would like the advantage of the points scored by the first team (the points of the first team minus the points of the second team) to be maximum. For that he can mentally choose the value of d. Help him to do that.
Input
The first line contains integer n (1 ≤ n ≤ 2·10^5) — the number of throws of the first team. Then follow n integer numbers — the distances of throws ai (1 ≤ ai ≤ 2·10 ^9).
Then follows number m (1 ≤ m ≤ 2·10^5) — the number of the throws of the second team. Then follow m integer numbers — the distances of throws of bi (1 ≤ bi ≤ 2·10 ^9).
Output
Print two numbers in the format a:b — the score that is possible considering the problem conditions where the result of subtraction a - b is maximum. If there are several such scores, find the one in which number a is maximum.
Examples
Input
3
1 2 3
2
5 6
Output
9:6
Input
5
6 7 8 9 10
5
1 2 3 4 5
Output
15:10
题目大意:给你A队和B队的进球距离两个数组,让你找到一个合适的三分线距离使得A对得分:B队得分最大(大于等于三分线的得3分,其余得2分)
一道标准的二分题目,只要三分线的大小就好了,然后计算A-B取最大的那个就行了。
不过这题需要枚举二分,将a,b和为c对c的每个元素进行二分,找到比这个值小到大的临界值,因此数组必须是有序的,我们就事先将a,b排序,二分查找的速度很快,再配上枚举的时间:O((n+m)*log(n)) 可以过
140ms,就算是1s的时限也完全没有问题
#include<cstdio>
#include<algorithm>
using namespace std;
int a[200005],b[200005],c[400200],n,m;
int ok1(int x);
int ok2(int x);
int main() {
int cnt=1;
scanf ("%d",&n);
for (int i=1; i<=n; i++) {
scanf ("%d",&a[i]);
c[cnt++]=a[i];
}
scanf ("%d",&m);
for (int i=1; i<=m; i++) {
scanf ("%d",&b[i]);
c[cnt++]=b[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+m);
sort(c+1,c+cnt);
c[cnt]=c[cnt-1]+1;
int max=-999999999,mark;
for (int i=1; i<=cnt; i++) {
int ab;
ab=ok1(c[i]-1)-ok2(c[i]-1); //枚举后a的分数与b的分数差
if (ab>max) {
max=ab;
mark=i;
}
}
printf ("%d:%d\n",ok1(c[mark]-1),ok2(c[mark]-1));
return 0;
}
int ok1(int x) { //对传进来的三分线进行二分查找
int sum1=0;
int l=1,r=n,mid;
for (int i=1; i<=20; i++) {
mid=(l+r)/2;
if (a[mid]<x) l=mid+1;
else if (a[mid]==x) break;
else r=mid-1;
}
while (a[mid]==a[mid+1]) {
mid++;
}
sum1=mid*2+(n-mid)*3;
return sum1;
}
int ok2(int x) {
int l=1,r=m,mid,sum2=0;
for (int i=1; i<=20; i++) {
mid=(l+r)/2;
if (b[mid]<x) l=mid+1;
else if (b[mid]==x) break;
else r=mid-1;
}
while (b[mid]==b[mid+1]) {
mid++;
}
sum2=mid*2+(m-mid)*3;
return sum2;
}