• [USACO2007 MAR]Balanced Lineup


    题目

    Description

    Farmer John 决定给他的奶牛们照一张合影,他让 N (1 ≤ N ≤ 50,000) 头奶牛站成一条直线,每头牛都有它的
    坐标(范围: 0..1,000,000,000)和种族(0或1)。一直以来 Farmer John 总是喜欢做一些非凡的事,当然这次照相
    也不例外。他只给一部分牛照相,并且这一组牛的阵容必须是“平衡的”。平衡的阵容,指的是在一组牛中,种族
    0和种族1的牛的数量相等。请算出最广阔的区间,使这个区间内的牛阵容平衡。区间的大小为区间内最右边的牛的
    坐标减去最做边的牛的坐标。输入中,每个种族至少有一头牛,没有两头牛的坐标相同。

    Input

    * 行 1: 一个整数: N 
    * 行 2..N + 1: 每行两个整数,为种族 ID 和 x 坐标。 

    Output

    * 行 1: 一个整数,阵容平衡的最大的区间的大小。 

    Sample Input

    7
    0 11
    1 10
    1 25
    1 12
    1 4
    0 13
    1 22

    Sample Output

    11

    HINT

    输入如下图所示


    输出如下图所示


    思路:

    看上面的样例,我们会发现0-10坐标区间内1比0多2个,0-22区间内1比0也多2个;

    我们也发现0-10坐标区间内1的个数为2个,0的个数为0个,0-22区间内1个数为4个,0的个数为2个;

    这两个区间的0,1个数相减,可以得出11-22区间内0,1的个数,同时我们会发现0和1的个数都为2;

    说明  0~x1,0~x2的0,1个数的差值相同,那么说明x1+1~x2的区间内0和1的个数相等;

    看起来像是统计前缀,其实也是统计前缀,但用更快的方法不需要直接统计

    我们可以先按坐标排序,然后把种族数字为0的改为-1;

    从0~x种族数字相加,就可以统计出0~x之间0,1个数的差值;

    注意(错误思路,但也看看助于理解)

    因为要找区间最大的,所以只把第一次出现0~x1的差值的x1坐标记下;

    然后往后找,找一个0~x2的差值与前面出现的差值相等,再x2-x1-1求出区间长度;

    但不一定每一个坐标都是有数的,

    如 1  1

        1  5

        0  7

     

    1   1 0

    1--5-7--

    x1=1, x2=7

    x2-x1-1 != 7-5

    所以记坐标是不行的;

    正确思路

    我们就需要记下每个坐标的序号

    如 1  4

        1  7

    坐标4的序号是1,坐标7的序号是2;

    那么求出差值相同的坐标0~x1,0~x2中x1,x2的序号y1,y2,再a[y2]-a[y1+1]求出区间长度,即可;

    最后用max求出最大区间长度就可以了


    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll a=0,f=1; char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
        return a*f;
    }
    struct sbbb
    {
        ll x,y;
    }a[500001];//结构体 x 代表每头牛的种族,y 是坐标 
    ll n,ans,num,f[500001];
    inline ll cmp(sbbb a,sbbb b)
    {
        return a.y<b.y;
    }//按坐标从小到大排序 
    int main()
    {
        n=read();
        for(ll i=1;i<=n;i++)
        {
            a[i].x=read();
            a[i].y=read();
            if(a[i].x==0)
                a[i].x=-1;//将每个种族为0的牛,把种族改为-1,方便统计 
        }
        sort(a+1,a+n+1,cmp);//排序 
        for(ll i=1;i<=n;i++)
        {
            num+=a[i].x;//计算差值 
            if(!f[num+n])//记下第一次出现的差值 因为差值可能是负数,所以下标加上n 
                f[num+n]=i;//记下坐标的序号 
            else
                ans=max(ans,a[i].y-a[f[num+n]+1].y);//统计最大区间长度 
        }
        printf("%lld",ans);
    }
  • 相关阅读:
    分治策略
    uva 11424
    lightoj 1214
    lightoj 1282 && uva 11029
    lightoj 1341
    zoj 2369 Two Cylinders
    几种素数筛法
    lightoj 1245
    hdoj 1299 Diophantus of Alexandria
    求前n项正整数的倒数和
  • 原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13049823.html
Copyright © 2020-2023  润新知