题目大意:

给定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[] , y[];
  14. bool in(Rec a){
  15. if(a.x[]>=x[] || a.y[]>=y[] || a.x[]<=x[] || a.y[]<=y[]) return false;
  16. return true;
  17. }
  18. }a , b , c , d;
  19.  
  20. void init(int n)
  21. {
  22. memset(mark , , sizeof(mark));
  23. for(int i= ; i<*n ; i++) G[i].clear();
  24. }
  25.  
  26. bool dfs(int u)
  27. {
  28. if(mark[u]) return true;
  29. if(mark[u^]) return false;
  30. mark[u] = true;
  31. S[k++] = u;
  32. for(int i= ; 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= ; i<*n ; i+=)
  40. if(!mark[i] && !mark[i^]){
  41. k= ;
  42. if(!dfs(i)){
  43. while(k) mark[S[--k]] = false;
  44. if(!dfs(i^)) 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=*a+p;
  53. int n=*b+q;
  54. //m,n互斥
  55. G[m].push_back(n^);
  56. G[n].push_back(m^);
  57. }
  58.  
  59. bool check(int m)
  60. {
  61. init(n);
  62. if(m&) m--;
  63. for(int i= ; i<n ; i++){
  64. for(int j=i+ ; j<n ; j++){
  65. //down , up 2*2 four case
  66. a.x[] = x[i]-m/ , a.y[] = y[i];
  67. a.x[] = x[i]+m/ , a.y[] = y[i];
  68. a.x[] = a.x[] , a.y[] = y[i]+m;
  69. a.x[] = a.x[] , a.y[] = y[i]+m;
  70.  
  71. b.x[] = x[j]-m/ , b.y[] = y[j];
  72. b.x[] = x[j]+m/ , b.y[] = y[j];
  73. b.x[] = b.x[] , b.y[] = y[j]+m;
  74. b.x[] = b.x[] , b.y[] = y[j]+m;
  75.  
  76. c.x[] = x[i]-m/ , c.y[] = y[i]-m;
  77. c.x[] = x[i]+m/ , c.y[] = y[i]-m;
  78. c.x[] = c.x[] , c.y[] = y[i];
  79. c.x[] = c.x[] , c.y[] = y[i];
  80.  
  81. d.x[] = x[j]-m/ , d.y[] = y[j]-m;
  82. d.x[] = x[j]+m/ , d.y[] = y[j]-m;
  83. d.x[] = d.x[] , d.y[] = y[j];
  84. d.x[] = d.x[] , d.y[] = y[j];
  85.  
  86. if(a.in(b)) add_clause(i , , j , );
  87. if(a.in(d)) add_clause(i , , j , );
  88. if(c.in(b)) add_clause(i , , j , );
  89. if(c.in(d)) add_clause(i , , j , );
  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= ; i<n ; i++){
  104. scanf("%d%d" , &x[i] , &y[i]);
  105. x[i]*= , y[i]*=;
  106. }
  107. int l= , r=1e5 , ret=l;
  108. while(l<=r){
  109. int m = (l+r)>>;
  110. if(check(m)) ret=m , l=m+;
  111. else r=m-;
  112. }
  113. printf("%d\n" , ret/);
  114. }
  115. return ;
  116. }

POJ 2296 二分+2-sat的更多相关文章

  1. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  2. Map Labeler (poj 2296 二分+2-SAT)

    Language: Default Map Labeler Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1815   Ac ...

  3. POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)

    POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...

  4. POJ - 2018 二分+单调子段和

    依然是学习分析方法的一道题 求一个长度为n的序列中的一个平均值最大且长度不小于L的子段,输出最大平均值 最值问题可二分,从而转变为判定性问题:是否存在长度大于等于L且平均值大于等于mid的字段和 每个 ...

  5. POJ 2296 Map Labeler(2-sat)

    POJ 2296 Map Labeler 题目链接 题意: 坐标轴上有N个点.要在每一个点上贴一个正方形,这个正方形的横竖边分别和x,y轴平行,而且要使得点要么在正方形的上面那条边的中点,或者在以下那 ...

  6. poj 3621 二分+spfa判负环

    http://poj.org/problem?id=3621 求一个环的{点权和}除以{边权和},使得那个环在所有环中{点权和}除以{边权和}最大. 0/1整数划分问题 令在一个环里,点权为v[i], ...

  7. POJ 3061 (二分+前缀和or尺取法)

    题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...

  8. POJ 2456 (二分)

    题目链接: http://poj.org/problem?id=2456 题目大意:n个房子,m头牛,房子有一个横坐标,问将m头牛塞进房子,每两头牛之间的最大间隔是多少. 解题思路: 不难看出应该二分 ...

  9. POJ 1064 (二分)

    题目链接: http://poj.org/problem?id=1064 题目大意:一堆棍子可以截取,问要求最后给出K根等长棍子,求每根棍子的最大长度.保留2位小数.如果小于0.01,则输出0.00 ...

随机推荐

  1. Oracle一个用户查询另一个用户的表数据

    1.两个用户是在不同的库,需要建立dblink 2.属于同一个库的不同用户 1)方法一:使用"用户名."的方式访问 例如:要从USER1账号访问USER2中的表TABLE2 A. ...

  2. 静态库冲突的解决办法:duplicate symbol

    昨天在做微信sdk和xmpp的集成,发现各自单独集成没问题,一起集成却总报错,百度了好一会儿才知道,这应该是库冲突造成的问题 然后参考了很多文章,跟着敲敲一遍,却发现问题多多,最后主要综合结合了这两个 ...

  3. hiho1093_spfa

    题目 SPFA模板题,题目中数据可能有两个点之间有多条边直接相连,使用 unordered_map< int, unordered_map< int, int>>, 来存储图的 ...

  4. Rest-Assured

    Rest-Assured完整的测试例子 http://blog.csdn.net/win7system/article/details/52468078 使用 Rest-assured 测试 Rest ...

  5. commonJS — DOM操作(for DOM)

    for DOM github: https://github.com/laixiangran/commonJS/blob/master/src/forDOM.js 代码 /** * Created b ...

  6. shell中for循环

    shell中for循环总结 最常用的就是遍历操作某一类文件,比如批量建索引. for i in `ls` do samtools faidx $i done 注意:for末尾不需要冒号(:),循环的代 ...

  7. linux笔记:linux系统安装-linux系统安装

    1.进入BIOS设置界面(在vmware虚拟机环境下,点击“虚拟机”菜单——电源——启动到BIOS设置): 2.把硬盘启动改成光盘启动(把光标移动到Boot菜单,再把光标置于CD-ROM Drive上 ...

  8. Jquery如何获得<iframe>嵌套页面中的元素

    DOM方法:父窗口操作IFRAME:window.frames["iframeSon"].documentIFRAME操作父窗口: window.parent.documentjq ...

  9. 默认选择radio的第一个

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. KVC与KVO的进阶使用

    本篇主要介绍键-值编码KVC,键值观察KVO的进阶使用的一些技巧主要是一下两个方面: KVC的集合操作符 KVO的手动实现方式 KVC集合操作符 关于集合操作符在苹果官方文档搜索Collection ...