bzoj 3760: suitang

Description

看过隋唐演义的都知道“宇文成都”是天下第二武功高手,就在隋炀帝杨广被奸臣宇文化及(也就是宇文成都的父亲)所逼死,宫中一片大乱,然“宇文成都”是一代豪杰,不愿通过这种方式来取得皇位,于是只身一人与上万瓦岗起义军决战,以死报国。(可惜啊,这么好的一个人,跟错了主)。 
宇文成都 只身一人击退起义军多位大将,就在这时,徐茂公准备下令让所有士兵冲上去活捉 宇文成都 ,然而 宇文成都 已经发现,他甚至记住了所有士兵的位置(在平面直角坐标系上的坐标,均为整数),他现在可以使用师傅传授的武功,将一个长度为L的正方形(平行于坐标轴,顶点坐标为整数)区域全部化为灰烬,L正比与他所消耗的功力,然而因为刚才运力过多,他现在只能使用3次武功,每一次的攻击正方形边长L都相同,三次使用武功后,他的体力总损耗为 L,每一次选择的正方形区域可以不同,也可以相交。现在他要把所有的n个士兵全部消灭,请问他最少要消耗多少体力(即最小正方形边长)?
(每次使用武功可将正方形内部的士兵全部消灭,边界上也算)

Input

第一行一个整数n(n个士兵),接下来n行,每行两个整数(xi,yi),表示每个士兵的坐标。

Output

共一行,一个整数,表示最小的体力消耗(L)。

Sample Input

10
10 3
4 8
9 1
1 6
5 5
9 6
6 7
7 8
2 1
9 7

Sample Output

5

HINT

100%的数据:1<=n<=20000;-1000000000<=xi,yi<=1000000000;

这不就是1052么!我程序都没改。。

二分L。

验证:

先取个可以覆盖所有点的最小矩形。感觉一下,肯定有一个正方形的一个角在这个矩形的一个角上。枚举四个位置。剩下的再这么做。再枚举,最后判断一个正方形可不可以覆盖所有就行了。

#include<cstdio>
#include<algorithm>
using namespace std;
struct point
{
     int x,y;
     bool flag;
}p[20001],tp[20001];
struct matrix
{
     int x,y;
}mat[11];
int maxx,maxy,minx,miny;
int n;
inline void find(int d,int lim)
{
     int i,j;
     bool flag;
     for(i=1;i<=n;i++)
     {
     	  flag=true;
          for(j=1;j<=d;j++)
          {
               if(p[i].x>=mat[j].x&&p[i].x<=mat[j].x+lim&&p[i].y>=mat[j].y&&p[i].y<=mat[j].y+lim)
               {
                    flag=false;
                    break;
               }
          }
          if(flag)
          {
               maxx=max(maxx,p[i].x);
               maxy=max(maxy,p[i].y);
               minx=min(minx,p[i].x);
               miny=min(miny,p[i].y);
          }
     }
}
inline bool check(int lim)
{
	 int p=1;
	 int i,j,k;
	 for(i=1;i<=4;i++) //1左上 2左下 3右上 4右下 
	 {
          maxx=-1000000000;
          maxy=-1000000000;
          minx=1000000000;
          miny=1000000000;
          find(0,lim);
          if(i==1)
          {
               mat[1].x=minx;
               mat[1].y=miny;
          }
          else if(i==2)
          {
               mat[1].x=maxx-lim;
               mat[1].y=miny;
          }
		  else if(i==3)
          {
               mat[1].x=minx;
               mat[1].y=maxy-lim;
          }
          else if(i==4)
          {
               mat[1].x=maxx-lim;
               mat[1].y=maxy-lim;
          }
          for(j=1;j<=4;j++)
          {
               maxx=-1000000000;
               maxy=-1000000000;
               minx=1000000000;
               miny=1000000000;
               find(1,lim);
               if(j==1)
               {
                    mat[2].x=minx;
                    mat[2].y=miny;
               }
               else if(j==2)
               {
                    mat[2].x=maxx-lim;
                    mat[2].y=miny;
               }
               else if(j==3)
               {
                    mat[2].x=minx;
                    mat[2].y=maxy-lim;
               }
               else if(j==4)
               {
                    mat[2].x=maxx-lim;
                    mat[2].y=maxy-lim;
               }
               maxx=-1000000000;
               maxy=-1000000000;
               minx=1000000000;
               miny=1000000000;
               find(2,lim);
               if(maxx-minx<=lim&&maxy-miny<=lim)
                    return true;
          }
     }
     return false;
}
int main()
{
     scanf("%d",&n);
     int i;
     int mix=1000000000,miy=1000000000,mxx=-1000000000,mxy=-1000000000;
     for(i=1;i<=n;i++)
     {
          scanf("%d%d",&p[i].x,&p[i].y);
          mxx=max(mxx,p[i].x);
          mxy=max(mxy,p[i].y);
          mix=min(mix,p[i].x);
          miy=min(miy,p[i].y);
     }
     int l=1,r=max(mxx-mix+1,mxy-miy+1);
     while(l<=r)
     {
          int mid=(l+r)/2;
          if(check(mid))
               r=mid-1;
          else
               l=mid+1;
     }
     printf("%d\n",l);
     return 0;
}
/*
5
0 0
0 1
0 2
0 3
0 4
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值