# bzoj1052 覆盖问题 二分答案 dfs

1、压的是对边，那么每个都在压对边，有一个正方形会压到三条边，就会压到一个角……

2、压的是邻边，一定会压到一个角……

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 const int maxn=(int)1e6+5;
7 int x[maxn],y[maxn],n,ax[4],ay[4],ajia[4],ajian[4];bool vis[maxn],now[4][maxn];int titai[3]={0,1,-1};
8 bool dfs(int num,int val)
9 {
10     if(num>3)
11     {
12         for(int i=1;i<=n;i++)
13             if(!vis[i])return 0;
14         return 1;
15     }
16     int maxx=-2147483647,minx=2147483647,maxy=-2147483647,miny=2147483647;
17     for(int i=1;i<=n;i++)
18         if(!vis[i])maxx=max(maxx,x[i]),minx=min(minx,x[i]),maxy=max(maxy,y[i]),miny=min(miny,y[i]);
19     if(max(maxx-minx,maxy-miny)<=val)return 1;
20     else if(num==3)return 0;
21     for(int i=1;i<=2;i++)
22         for(int j=1;j<=2;j++)
23         {
24             ajia[num]=titai[i],ajian[num]=titai[j];
25             if(ajia[num]==1&&ajian[num]==1)ax[num]=minx,ay[num]=miny;
26             else if(ajia[num]==1&&ajian[num]==-1)ax[num]=minx,ay[num]=maxy;
27             else if(ajia[num]==-1&&ajian[num]==1)ax[num]=maxx,ay[num]=miny;
28             else if(ajia[num]==-1&&ajian[num]==-1)ax[num]=maxx,ay[num]=maxy;
29             for(int i=1;i<=n;i++)
30                 if(!vis[i]&&((ajia[num]==1&&ajian[num]==1&&ax[num]<=x[i]&&ay[num]<=y[i]&&ax[num]+val>=x[i]&&ay[num]+val>=y[i])||(ajia[num]==1&&ajian[num]==-1&&ax[num]<=x[i]&&ay[num]>=y[i]&&ax[num]+val>=x[i]&&ay[num]-val<=y[i])||(ajian[num]==1&&ajia[num]==-1&&ay[num]<=y[i]&&ax[num]>=x[i]&&ay[num]+val>=y[i]&&ax[num]-val<=x[i])||(ajian[num]==-1&&ajia[num]==-1&&ay[num]>=y[i]&&ax[num]>=x[i]&&ay[num]-val<=y[i]&&ax[num]-val<=x[i])))vis[i]=now[num][i]=1;
31             int t=dfs(num+1,val);
32             for(int i=1;i<=n;i++)if(now[num][i])vis[i]=now[num][i]=0;
33             if(t)return 1;
34         }
35     return 0;
36 }
37 bool check(int val)
38 {
39     return dfs(1,val);
40 }
41 int haha()
42 {
43     scanf("%d",&n);int maxx=-2147483647,minx=2147483647,maxy=-2147483647,miny=2147483647;
44     for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]),maxx=max(maxx,x[i]),minx=min(minx,x[i]),maxy=max(maxy,y[i]),miny=min(miny,y[i]);
45     int l=1,r=max(maxx-minx,maxy-miny),mid;
46     while(l<=r)
47     {
48         mid=(l+r)>>1;
49         if(check(mid))r=mid-1;
50         else l=mid+1;
51     }
52     printf("%d\n",l);
53 }
54 int sb=haha();
55 int main(){;}
bzoj1052

posted @ 2017-09-22 16:45  ccc000111  阅读(180)  评论(0编辑  收藏