• Problem: [Usaco2016 Feb]Load Balancing


    Problem: [Usaco2016 Feb]Load Balancing

    Time Limit: 1 Sec Memory Limit: 128 MB

    Description

    农民约翰的N只牛分别站在他的二维农场的不同位置(x1,y1)…(xn,yn)(1<=N<=100,xi和yi是正整奇数,最大值
    是B)。他想建一排无限长度的南北方向的满足等式x=a的围栏来把他的农场分成两部分(a是一个偶数,确保了不
    会使围栏建在任何一只牛的位置上)。他也想建一个无限长度的东西方向的满足等式y=b的围栏(b也是偶数)。这
    两个围栏在(a,b)点相交,并把农场分成了四个区域。约翰想选一对a和b使四个区域是"平衡"的,即不要让一个
    区域包含太多的牛。令M为四个区域中牛的数量的最大值,约翰想使M尽量的小。请帮他求出最小的M。对于前5组数
    据,B保证最大为100。在所有数据中,B保证最大为1,000,000。

    Input

    第一行包含两个整数N和B。接下来的N行每行包含一只牛的位置x和y

    Output

    输出M的最小值

    Sample Input

    7 10
    7 3
    5 5
    9 7
    3 1
    7 7
    5 3
    9 1

    Sample Output

    2
    代码如下

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,pos[100050],sum[100050],now;
    int c[100050],ans,l,r,tl,tr,tot;
    struct node {
        int x,y,tmp;
        bool operator<(const node & p)const {
            return x==p.x? tmp<p.tmp:x<p.x;
        }
    } num[100050];
    bool cmp(int a,int b) {
        return num[a].tmp<num[b].tmp;
    }
    void calc_push(int u) {
        while(u<=now) {
            ++c[u];
            u+=u&-u;
        }
    }
    int calc_ask(int u) {
        int cnt=0;
        while(u) {
            cnt+=c[u];
            u-=u&-u;
        }
        return cnt;
    }
    int check(int u) {
        int tmp=calc_ask(u);
        int ent=max(max(tmp,tot-1-tmp),max(sum[u]-tmp,n-(sum[u]-tmp+tot-1)));
        ans=min(ans,ent);
        return ent;
    }
    void calc() {
        l=1,r=now;
        while(l<r) {
            tl=((l<<1)+r)/3;
            tr=(l+(r<<1))/3;
            if(l==tl)    ++tl;
            if(r==tr)     --tr;
            if(check(tl)<check(tr))     r=tr;
            else     l=tl;
        }
    }
    int main() {
        scanf("%d",&n);
        scanf("%d",&ans);
        ans=n;
        for(int i=1; i<=n; ++i) {
            scanf("%d%d",&num[i].x,&num[i].tmp);
            pos[i]=i;
        }
        sort(num+1,num+n+1);
        sort(pos+1,pos+n+1,cmp);
        for(int i=1; i<=n; ++i) {
            if(num[pos[i]].tmp!=num[pos[i-1]].tmp) {
                ans=min(ans,max(sum[now],n-sum[now]));
                sum[now+1]=sum[now];
                ++now;
            }
            num[pos[i]].y=now;
            ++sum[now];
        }
        for(int i=1; i<=n; i=tot) {
            tot=i;
            while(num[tot].x==num[i].x)
                calc_push(num[tot++].y);
            calc();
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    基于I2C总线的MPU6050学习笔记
    基于I2C总线的0.96寸OLED显示屏驱动
    I2C总线协议的软件模拟实现方法
    I2C总线通讯协议
    Exynos4412从SD卡启动的简单网络文件系统制作
    多版本 PHP 环境下,使用指定版本运行composer
    腾讯云服务器 lnmp 开启 MySQL 远程访问权限
    MySQL添加新用户和新增权限
    Laravel 框架创建软链接
    Git 保存登录凭证
  • 原文地址:https://www.cnblogs.com/ZhaoChongyan/p/11740449.html
Copyright © 2020-2023  润新知