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

BZOJ1052

时间:2015-08-25 21:49:42      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:二分   暴力法   

传送门: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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

BZOJ1052

标签:二分   暴力法   

原文地址:http://blog.csdn.net/le_ballon_rouge/article/details/47982035

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