zoukankan      html  css  js  c++  java
  • POJ 2296 二分+2-sat

     题目大意:

    给定n个点,给每个点都安排一个相同的正方形,使这个点落在正方形的下底边的中间或者上底边的中间,并让这n个正方形不出现相互覆盖,可以共享同一条边,求

    这个正方形最大的边长

    这里明显看出n个点,每个点都只有在上底边和下底边两种选择,所以这里是2-sat解决

    这里全都是整数,而因为点在正方形的中间,所以/2后会有小数

    我这里初始将所有点都扩大两倍,那么答案必然扩大两倍,所以我们二分只考虑边长为偶数的情况即可,这样计算结果就不会出现小数了

    最后将答案除以2便是

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 #define N 210
      8 int n , S[N] , x[N] , y[N] , k;
      9 vector<int> G[N];
     10 bool mark[N];
     11 
     12 struct Rec{
     13     int x[4] , y[4];
     14     bool in(Rec a){
     15         if(a.x[0]>=x[1] || a.y[0]>=y[2] || a.x[1]<=x[0] || a.y[2]<=y[0]) return false;
     16         return true;
     17     }
     18 }a , b , c , d;
     19 
     20 void init(int n)
     21 {
     22     memset(mark , 0 , sizeof(mark));
     23     for(int i=0 ; i<2*n ; i++) G[i].clear();
     24 }
     25 
     26 bool dfs(int u)
     27 {
     28     if(mark[u]) return true;
     29     if(mark[u^1]) return false;
     30     mark[u] = true;
     31     S[k++] = u;
     32     for(int i=0 ; i<G[u].size() ; i++)
     33         if(!dfs(G[u][i])) return false;
     34     return true;
     35 }
     36 
     37 bool solve(int n)
     38 {
     39     for(int i=0 ; i<2*n ; i+=2)
     40         if(!mark[i] && !mark[i^1]){
     41             k= 0;
     42             if(!dfs(i)){
     43                 while(k) mark[S[--k]] = false;
     44                 if(!dfs(i^1)) return false;
     45             }
     46         }
     47     return true;
     48 }
     49 
     50 void add_clause(int a , int p , int b , int q)
     51 {
     52     int m=2*a+p;
     53     int n=2*b+q;
     54     //m,n互斥
     55     G[m].push_back(n^1);
     56     G[n].push_back(m^1);
     57 }
     58 
     59 bool check(int m)
     60 {
     61     init(n);
     62     if(m&1) m--;
     63     for(int i=0 ; i<n ; i++){
     64         for(int j=i+1 ; j<n ; j++){
     65             //down , up 2*2 four case
     66             a.x[0] = x[i]-m/2 , a.y[0] = y[i];
     67             a.x[1] = x[i]+m/2 , a.y[1] = y[i];
     68             a.x[2] = a.x[1]   , a.y[2] = y[i]+m;
     69             a.x[3] = a.x[0]   , a.y[3] = y[i]+m;
     70 
     71             b.x[0] = x[j]-m/2 , b.y[0] = y[j];
     72             b.x[1] = x[j]+m/2 , b.y[1] = y[j];
     73             b.x[2] = b.x[1]   , b.y[2] = y[j]+m;
     74             b.x[3] = b.x[0]   , b.y[3] = y[j]+m;
     75 
     76             c.x[0] = x[i]-m/2 , c.y[0] = y[i]-m;
     77             c.x[1] = x[i]+m/2 , c.y[1] = y[i]-m;
     78             c.x[2] = c.x[1]   , c.y[2] = y[i];
     79             c.x[3] = c.x[0]   , c.y[3] = y[i];
     80 
     81             d.x[0] = x[j]-m/2 , d.y[0] = y[j]-m;
     82             d.x[1] = x[j]+m/2 , d.y[1] = y[j]-m;
     83             d.x[2] = d.x[1]   , d.y[2] = y[j];
     84             d.x[3] = d.x[0]   , d.y[3] = y[j];
     85 
     86             if(a.in(b)) add_clause(i , 0 , j , 0);
     87             if(a.in(d)) add_clause(i , 0 , j , 1);
     88             if(c.in(b)) add_clause(i , 1 , j , 0);
     89             if(c.in(d)) add_clause(i , 1 , j , 1);
     90         }
     91     }
     92     return solve(n);
     93 }
     94 
     95 int main()
     96 {
     97   //  freopen("in.txt" , "r" , stdin);
     98     int T;
     99     scanf("%d" , &T);
    100     while(T--)
    101     {
    102         scanf("%d" , &n);
    103         for(int i=0 ; i<n ; i++){
    104             scanf("%d%d" , &x[i] , &y[i]);
    105             x[i]*=2 , y[i]*=2;
    106         }
    107         int l=0 , r=1e5 , ret=l;
    108         while(l<=r){
    109             int m = (l+r)>>1;
    110             if(check(m)) ret=m , l=m+1;
    111             else r=m-1;
    112         }
    113         printf("%d
    " , ret/2);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    css盒模型不同浏览器下解释不同 解决办法
    【META http-equiv="Content-Type" Content="text/html; Charset=*】意义详解
    淘宝2015年秋招在线笔试题
    mouseleave mouseout时候悬浮框不应该消失的时候消失了 css 解决办法
    ACM知识点分类
    2019牛客多校第九场 B.Quadratic equation
    扫描线算法
    可持久化数据结构(模板)
    luogu SP3267 DQUERY
    luogu2633 Count on a tree(树上LCA+主席树求区间第k小)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4681834.html
Copyright © 2011-2022 走看看