BZOJ1052

传送门:BZOJ1052

傻逼题。

二分一个长度,注意到每次正方形必然落在某个角上,枚举判断即可。

好久不见的1A……

代码上的小细节见下。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int INF=0x3f3f3f3f;

struct Point{
    int x,y;
    Point(){
        x=y=0;
    }
};

struct Matrix{
    Point basic[20005];
    int size;
    Matrix(){
        size=0;
    }
};

int n;
Matrix T;

void GetPoint(Point& BLC,Point& RC,Matrix a)    //获得矩形a的左下角和右下角
{
    int minx=INF,maxx=-INF;
    int miny=INF,maxy=-INF;
    for(int i=1;i<=a.size;i++){
        minx=min(minx,a.basic[i].x);
        maxx=max(maxx,a.basic[i].x);
        miny=min(miny,a.basic[i].y);
        maxy=max(maxy,a.basic[i].y);
    }
    BLC.x=minx;BLC.y=miny;
    RC.x=maxx;RC.y=maxy;
}

void Cut(Matrix& a,Point BLC,Point RC)     //擦掉正方形覆盖区域
{
    Matrix b;
    for(int i=1;i<=a.size;i++)
        if(!((BLC.x<=a.basic[i].x&&a.basic[i].x<=RC.x)&&(BLC.y<=a.basic[i].y&&a.basic[i].y<=RC.y))){
            b.size++;
            b.basic[b.size].x=a.basic[i].x;
            b.basic[b.size].y=a.basic[i].y;
        }
    a=b;
}

bool Check(Matrix& a,int T)     //判断矩阵能否被正方形完全覆盖
{
    Point BLC,RC;
    GetPoint(BLC,RC,a);
    return ((RC.x-BLC.x+1<=T)&&(RC.y-BLC.y+1<=T));
}

void Update(Matrix& a,int kind,int T)   //修改矩形
{
    Point BLC,RC;
    GetPoint(BLC,RC,a);
    //if(kind==1)   //左下角
        //RC.x=BLC.x+T-1,RC.y=BLC.y+T-1;
    if(kind==2)     //左上角
        BLC.y=RC.y+1-T;
    if(kind==3)    //右上角
        BLC.x=RC.x+1-T,BLC.y=RC.y+1-T;
    if(kind==4)     //右下角
        BLC.x=RC.x+1-T;
    RC.x=BLC.x+T-1,RC.y=BLC.y+T-1;
    Cut(a,BLC,RC);
}

bool Judge(Matrix a,int T)  //暴力枚举,判断给定长度是否可行
{
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++){
            Matrix b=a;
            Update(b,i,T);
            Update(b,j,T);
            if(Check(b,T))
                return true;
        }
    return false;
}

void Solve(Matrix a)    //求解问题
{
    int l=1,r=INF;
    while(l<r){
        int mid=(l+r)/2;
        bool flag=Judge(a,mid);
        if(flag)
            r=mid;
        else
            l=mid+1;
    }
    printf("%d\n",l-1);
}

void Readdata()
{
    freopen("loli.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&T.basic[i].x,&T.basic[i].y);
    T.size=n;
}

void Close()
{
    fclose(stdin);
    fclose(stdout);
}

int main()
{
    Readdata();
    Solve(T);
    Close();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值