码迷,mamicode.com
首页 > 其他好文 > 详细

投篮练习【二分】

时间:2018-04-19 01:51:11      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:++   格式   个数   链接   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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!