标签:++ 格式 个数 链接 label tail 特殊情况 练习 blank
题目链接:http://www.bjfuacm.com/problem/375/
发布时间: 2018年4月18日 17:36 最后更新: 2018年4月18日 17:39 时间限制: 1000ms 内存限制: 128M
小A特别喜欢看篮球,他也了解在篮球场上每次进攻投进篮都会获得2分或者3分。某天,他看了一场特别的投篮比赛,这场比赛的得分计算方式为:当投篮的距离不超过d时,就会获得2分;当投篮的距离大于d时,就会获得3分。d是一个非负整数。这场比赛中,分为红队和蓝队,红队是小A支持的球队,假设红队的总得分为a,蓝队的总得分为b,于是小A想知道,当d为何值时,a-b的值最大。
输入第一行包含一个整数n(1<=n<=2·10^5),代表红队的投篮次数,接下来一行包含n个整数,代表红队每次投篮的距离ai(1<=ai<=2·10^9)
输入第三行包含一个整数m(1<=m<=2·10^5),代表蓝队的投篮次数,接下来一行包含m个整数,代表蓝队每次投篮的距离bi(1<=bi<=2·10^9)
输出占一行。包含两个整数a和b,输出格式为"a:b",表示当d取某值时,a-b的值最大,其中a代表红队的得分,b代表蓝队的得分。如果存在多组最大的情况,输出其中a最大的一组。
3
1 2 3
2
5 6
9:6
5
6 7 8 9 10
5
1 2 3 4 5
15:10
#include<cstdio> #include<algorithm> #define MAX 200000 #define NUM 2e9 using namespace std; int a[MAX + 10], b[MAX + 10], pos[2 * MAX + 10];//vis数组存红队和蓝队的位置 int cal(int l, int r, int dis[], int i) { int num = r + 1;//这里num存的是该队投篮数组中元素个数,方便后面计算分数 int mid; while (l<r)//计算该队的得分,找到第一个大于pos[i]的位置 { mid = l + r >> 1; if (dis[mid] <= pos[i]) l = mid + 1; else r = mid; } if (dis[l] <= pos[i])//考虑特殊情况,该队最远的位置都不如pos[i]远 l++; return l * 2 + (num - l) * 3; } int main() { int i, n, m; while (scanf("%d", &n) != EOF) { for (i = 0; i<n; i++) { scanf("%d", &a[i]); pos[i + 1] = a[i];//红队的位置放进vis数组中 } scanf("%d", &m); pos[0] = 0;//0也放进vis数组中 pos[n + m + 1] = NUM;//2*10^9也放进vis数组中 for (i = 0; i<m; i++) { scanf("%d", &b[i]); pos[i + n + 1] = b[i];//蓝队的位置放进vis数组中 } sort(a, a + n); sort(b, b + m); int posn = -2e5;//存a-b的最大值,因为最小就是-2*10^5,所以这里取-2e5 int pr1 = 0, pr2 = 0; for (i = 0; i <= n + m + 1; i++)//枚举每个位置 { int l = 0, r = n - 1, sco1, sco2; sco1 = cal(l, r, a, i);//计算红队的得分 l = 0, r = m - 1; sco2 = cal(l, r, b, i);//计算蓝队的得分 if (posn<sco1 - sco2) { posn = sco1 - sco2; pr1 = sco1; pr2 = sco2; } else if (posn == sco1 - sco2 && pr1<sco1) { pr1 = sco1; pr2 = sco2; } } printf("%d:%d\n", pr1, pr2); } return 0; }
2018-04-19
标签:++ 格式 个数 链接 label tail 特殊情况 练习 blank
原文地址:https://www.cnblogs.com/00isok/p/8878755.html