zoukankan      html  css  js  c++  java
  • bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍 ——中位数排序

    Description

    经过多年的积蓄,农夫JOHN决定造一个新的牛舍。他知道所有N(2 <= N <= 10,000)头牛的吃草位置,所以他想把牛舍造在最方便的地方。 每一头牛吃草的位置是一个整数点(X_i, Y_i) (-10,000 <= X_i <= 10,000; -10,000 <= Y_i <= 10,000)。 没有两头牛的吃草位置是相邻的。 JOHN决定把牛舍造在一个没有牛吃草的整数点上。如果牛舍在(X, Y),在(X_i, Y_i)的牛到牛舍的距离是|X-X_i|+|Y-Y_i|。 JOHN把牛舍造在哪儿才能使所有牛到牛舍的距离和最低?

    Input

    第1行: 一个数,N。

    第2~N+1行:第i+1行 包含第i头牛的位置(X_i, Y_i)。

    Output

    第1行: 两个数,最小距离和和所有可能达到这个距离和的牛舍位置的数目。

    Sample Input

    4
    1 -3
    0 1
    -2 1
    1 -1

    输入解释:

    一共有4头牛,位置分别为(1, -3), (0, 1), (-2, 1), 和(1, -1).

    Sample Output

    10 4

    输出解释:
    最小距离和是10,可以在牛舍位于 (0, -1), (0, 0), (1, 0), (1, 1)时达到。
    ——————————————————————————————————
    这道题很容易想到中位数 x y 也很明显可以单独考虑
    但是要分奇数偶数的情况 奇数要判这个点是否有牛 没有就考虑旁边四个 
    偶数就直接矩阵大小减去里面的牛就可以了 233
    不过我发现题目似乎没有说没有牛在同一位置吃草 那么这里会不会有问题呢QAQ
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    using std::sort;
    using std::min;
    const int M=2e4+7;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int ans,sum,n,x[M],y[M];
    struct pos{
        int x,y;
        bool operator <(const pos& h)const{return h.x!=x?h.x<x:h.y<y;}
    }q[M];
    std::map<pos,bool>vis;
    int main(){
        n=read();
        for(int i=1;i<=n;i++){
            x[i]=read(); y[i]=read();
            q[i].x=x[i]; q[i].y=y[i];
        }
        sort(x+1,x+1+n); sort(y+1,y+1+n);
        int x1=x[(n+1)/2],y1=y[(n+2)/2],x2=x[(n+2)/2],y2=y[(n+1)/2];
        if(x1==x2&&y1==y2){
            bool f=false;
            for(int i=1;i<=n;i++)if(q[i].x==x1&&q[i].y==y1){f=true; break;}
            if(!f){
                ans=1;
                for(int i=1;i<=n;i++){
                    sum=sum+abs(q[i].x-x1);
                    sum=sum+abs(q[i].y-y1);
                }
            }
            else{
                int nx=x1,ny=y1-1;
                for(int i=1;i<=n;i++){
                    sum=sum+abs(q[i].x-nx);
                    sum=sum+abs(q[i].y-ny);
                }
                ans=1; nx=x1; ny=y1+1;
                int now=0;
                for(int i=1;i<=n;i++){
                    now=now+abs(q[i].x-nx);
                    now=now+abs(q[i].y-ny);
                }
                if(sum>now) ans=1;
                if(sum==now) ans++;
                nx=x1+1; ny=y1;
                now=0;
                for(int i=1;i<=n;i++){
                    now=now+abs(q[i].x-nx);
                    now=now+abs(q[i].y-ny);
                }
                if(sum>now) ans=1;
                if(sum==now) ans++;
                now=0;
                nx=x1-1; ny=y1;
                for(int i=1;i<=n;i++){
                    now=now+abs(q[i].x-nx);
                    now=now+abs(q[i].y-ny);
                }
                if(sum>now) ans=1;
                if(sum==now) ans++;
            }
            printf("%d %d
    ",sum,ans);
        }
        else{
            ans=(x2-x1+1)*(y1-y2+1);
            for(int i=1;i<=n;i++){
                if(q[i].x>=x1&&q[i].x<=x2&&q[i].y>=y2&&q[i].y<=y1){
                    if(!vis[(pos){q[i].x,q[i].y}]){ans--; vis[(pos){q[i].x,q[i].y}]=1;}
                }
                sum=sum+abs(q[i].x-x1);
                sum=sum+abs(q[i].y-y1);
            }
            printf("%d %d
    ",sum,ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    导数的定义(一些常用函数的求导公式)
    ubuntu后台运行命令行
    数学公式做图网站
    导数可导性与连续性关系
    nutch 二次开发
    matplotlib绘制精美的图表(这是教程哦)
    JS获取今天和上个月的今天
    js修改url参数,无刷新更换页面url
    给网页复制的内容添加东西
    MySQL下载安装详情教程
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7604078.html
Copyright © 2011-2022 走看看