03:矩形分割

来源:互联网 发布:淘宝月销量 编辑:程序博客网 时间:2024/06/02 07:32

原题链接

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

平面上有一个大矩形,其左下角坐标(00),右上角坐标(R,R)。大矩形内部包含一些小矩形,小矩形都平行于坐标轴且互不重叠。所有矩形的顶点都是整点。要求画一根平行于y轴的直线x=kk是整数,使得这些小矩形落在直线左边的面积必须大于等于落在右边的面积,且两边面积之差最小。并且,要使得大矩形在直线左边的的面积尽可能大。注意:若直线穿过一个小矩形,将会把它切成两个部分,分属左右两侧。

输入
第一行是整数R,表示大矩形的右上角坐标是(R,R) (1 <= R <= 1,000,000)。
接下来的一行是整数N,表示一共有N个小矩形(0 < N <= 10000)。
再接下来有N 行。每行有4个整数,L,T, W 和 H, 表示有一个小矩形的左上角坐标是(L,T),宽度是W,高度是H (0<=L,T <= R, 0 < W,H <= R). 小矩形不会有位于大矩形之外的部分。
输出
输出整数n,表示答案应该是直线 x=n。 如果必要的话,x=R也可以是答案。
样例输入
100021 1 2 15 1 2 1
样例输出
5

源码

#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;long long l,r,mid;long long zuo,you,sum,ans,R,n;struct node{    long long x,y,xx,h;    long long s;}ta[10010];long long love(long mid){    int i;    long long s1,s2;    s1=0;s2=0;    for (i=0;i<=n;i++)    {        if (ta[i].xx<=mid) s1+=ta[i].s;        else if (ta[i].x>=mid) s2+=ta[i].s;        else         {            s1+=(mid-ta[i].x)*ta[i].h;            s2+=(ta[i].xx-mid)*ta[i].h;        }    }    return s1-s2;}int main(){    long long  x,y,w,h,i;    long long ans,maxx=-1;    scanf("%lld",&R);    scanf("%lld",&n);    for (i=1;i<=n;i++)    {        scanf("%lld%lld%lld%lld",&x,&y,&w,&h);         ta[i].x=x;ta[i].y=y;ta[i].xx=x+w;ta[i].h=h;ta[i].s=w*h;        if (x+w>maxx) maxx=x+w;    }    l=0;r=R;    while (l+1<r)    {        mid=(l+r)/2;        sum=love(mid);        if (sum>0) r=mid;        else if (sum<=0) l=mid;        else if (sum==0) {printf("%d",mid);return 0;}    }    zuo=love(l);    you=love(r);    if (abs(zuo)>=abs(you)) ans=r;    else ans=l;    if (ans==maxx) ans=R;    printf("%lld",ans);} 


原创粉丝点击