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

[USACO2007 MAR]Balanced Lineup

时间:2020-06-05 23:24:44      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:统计   +=   注意   --   排序   sam   lld   题目   getc   

题目

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);
}

 

 

 

[USACO2007 MAR]Balanced Lineup

标签:统计   +=   注意   --   排序   sam   lld   题目   getc   

原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13049823.html

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