从TLE的暴力枚举 到 13313MS的扫描线  再到 1297MS的简化后的扫描线,简直感觉要爽翻啦。然后满怀欣喜的去HDU交了一下,直接又回到了TLE.....泪流满面

虽说HDU的时限是2000MS 可是数据也忒强了点吧,真心给HDU跪了。

题意:给定平面上的N个点,属性分别标记为0和1,然后找一条直线,直线上的点全部溶解,一侧的1溶解,另一侧的0溶解。求出最多能溶解的点的个数。

思路:最直接的思路就是O(N^3)的暴力枚举,Discuss里面貌似有大牛过了,肯能是我太过暴力了吧,果断Tle了,然后换成了枚举单个点,然后极角排序+扫描线,

跑了13313MS。然后优化了一下跑了1297MS。下面说一下扫描线的思路。

首先,确定射线v1,v2与X轴正方向的角度,一个为0,一个为PI,然后同时旋转,每碰到一个点就计算一次v1,v2之间的及在两条射线上的点。

直到v1与X轴的方向 >= PI ,当前这一次计算结束,继续枚举下一个点。

这就是13313MS那份代码的思路,显然扫描线是没错的,但是有一些点被重复计算了,其实我们只需要计算α角区域内的点的个数,通过它来维

护v1,v2区域内的点的个数,优化后用时就减少到了1297MS,但是在HDU依然过不了......

POJ AC_Code 1297MS

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <queue>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <string>
  9.  
  10. #define LL long long
  11. #define EPS (1e-8)
  12.  
  13. using namespace std;
  14.  
  15. const double PI = acos(-1.0);
  16.  
  17. struct P
  18. {
  19. double a;
  20. int x,y,mark;
  21. } pa[1010],p[1010];
  22.  
  23. double Cal_Angle(P p1,P p2)
  24. {
  25. if(p1.x == p2.x && p1.y == p2.y)
  26. return -100.0;
  27. P v;
  28. v.x = p2.x - p1.x;
  29. v.y = p2.y - p1.y;
  30. if(p1.y <= p2.y)
  31. return acos(v.x/sqrt(v.x*v.x + v.y*v.y));
  32. return 2.0*PI - acos(v.x/sqrt(v.x*v.x + v.y*v.y));
  33. }
  34.  
  35. void Cal_Angle(P p,P *pa,int n)
  36. {
  37. for(int i = 0; i < n; ++i)
  38. {
  39. pa[i].a = Cal_Angle(p,pa[i]);
  40. }
  41. }
  42.  
  43. bool cmp_angle(P p1,P p2)
  44. {
  45. return p1.a < p2.a;
  46. }
  47.  
  48. int main()
  49. {
  50. int n,i,j,k,l,d;
  51. int Max,tl,tr,b,w,s1,s0,s2,s3;
  52. double xm,pil,pir;
  53. P vec;
  54. while(scanf("%d",&n) && n)
  55. {
  56. b = 0;
  57. w = 0;
  58. for(i = 0; i < n; ++i)
  59. {
  60. scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].mark);
  61. pa[i] = p[i];
  62. if(pa[i].mark)
  63. b++;
  64. else
  65. w++;
  66. }
  67.  
  68. Max = -1;
  69.  
  70. for(i = 0; i < n; ++i)
  71. {
  72. Cal_Angle(p[i],pa,n);
  73. sort(pa,pa+n,cmp_angle);
  74.  
  75. pir = pa[1].a;
  76. pil = pir + PI;
  77.  
  78. s1 = s0 = s2 = s3 = 0;
  79.  
  80. for(j = 1; j < n && pa[j].a < pil; ++j)
  81. {
  82. if(pa[j].a == pir)
  83. {
  84. if(pa[j].mark)
  85. s3++;
  86. else
  87. s2++;
  88. }
  89. else
  90. {
  91. if(pa[j].mark)
  92. s1++;
  93. else
  94. s0++;
  95. }
  96. }
  97.  
  98. for(d = j; d < n && pa[d].a == pil; ++d)
  99. {
  100. if(pa[d].mark)
  101. s3++;
  102. else
  103. s2++;
  104. }
  105.  
  106. if(pa[0].mark)
  107. s3++;
  108. else
  109. s2++;
  110.  
  111. tr = s0 + (b-s1)+s2;
  112. tl = s1 + (w-s0)+s3;
  113.  
  114. if(tr > Max || tl > Max)
  115. Max = tr > tl ? tr : tl;
  116.  
  117. k = 1;
  118.  
  119. while(pir < PI && j < n)
  120. {
  121. for(; k < n && pir == pa[k].a; ++k)
  122. {
  123. if(pa[k].mark)
  124. --s3;
  125. else
  126. --s2;
  127. }
  128. pir = pa[k].a;
  129. if(pir > PI)
  130. break;
  131. for(l = k; l < n && pir == pa[l].a; ++l)
  132. {
  133. if(pa[l].mark)
  134. {
  135. ++s3;
  136. --s1;
  137. }
  138. else
  139. {
  140. ++s2;
  141. --s0;
  142. }
  143. }
  144. for(; j < n && pa[j].a == pil; ++j)
  145. {
  146. if(pa[j].mark)
  147. {
  148. --s3;
  149. ++s1;
  150. }
  151. else
  152. {
  153. --s2;
  154. ++s0;
  155. }
  156. }
  157.  
  158. pil = pir+PI;
  159.  
  160. for(; j < n && pa[j].a < pil; ++j)
  161. {
  162. if(pa[j].mark)
  163. {
  164. ++s1;
  165. }
  166. else
  167. {
  168. ++s0;
  169. }
  170. }
  171.  
  172. for(d = j; d < n && pa[d].a == pil ; ++d)
  173. {
  174. if(pa[d].mark)
  175. ++s3;
  176. else
  177. ++s2;
  178. }
  179. tr = s0 + (b-s1)+s2;
  180. tl = s1 + (w-s0)+s3;
  181. if(tr > Max || tl > Max)
  182. {
  183. Max = tr > tl ? tr : tl;
  184. }
  185. }
  186. }
  187. printf("%d\n",Max);
  188. }
  189. return 0 ;
  190. }

POJ AC_Code 13313MS

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <queue>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <string>
  9.  
  10. #define LL long long
  11. #define EPS (1e-8)
  12.  
  13. using namespace std;
  14.  
  15. const double PI = acos(-1);
  16.  
  17. struct P
  18. {
  19. double x,y,a;
  20. int mark;
  21. }pa[1010],p[1010];
  22.  
  23. double Cal_Angle(P p1,P p2)
  24. {
  25. if(p1.x == p2.x && p1.y == p2.y)
  26. return -100.0;
  27. P v;
  28. v.x = p2.x - p1.x;
  29. v.y = p2.y - p1.y;
  30. if(p1.y <= p2.y)
  31. return acos(v.x/sqrt(v.x*v.x + v.y*v.y));
  32. return 2.0*PI - acos(v.x/sqrt(v.x*v.x + v.y*v.y));
  33. }
  34.  
  35. void Cal_Angle(P p,P *pa,int n)
  36. {
  37. for(int i = 0;i < n; ++i)
  38. {
  39. pa[i].a = Cal_Angle(p,pa[i]);
  40. }
  41. }
  42.  
  43. bool cmp_angle(P p1,P p2)
  44. {
  45. return p1.a < p2.a;
  46. }
  47.  
  48. int main()
  49. {
  50. int n,i,j,k;
  51. int tm1,tm0,tm2,tm3,Max,t1,t2,b,w;
  52. double xm,pil,pir;
  53. P vec;
  54. while(scanf("%d",&n) && n)
  55. {
  56. b = 0;
  57. w = 0;
  58. for(i = 0;i < n; ++i)
  59. {
  60. scanf("%lf %lf %d",&p[i].x,&p[i].y,&p[i].mark);
  61. pa[i] = p[i];
  62. if(pa[i].mark)
  63. b++;
  64. else
  65. w++;
  66. }
  67.  
  68. Max = -1;
  69.  
  70. for(i = 0;i < n; ++i)
  71. {
  72. Cal_Angle(p[i],pa,n);
  73. sort(pa,pa+n,cmp_angle);
  74. pir = pa[0].a;
  75. j = 1;
  76. while(pir <= PI && j < n)
  77. {
  78. for(;j < n && pa[j].a == pir; ++j)
  79. ;
  80. pir = pa[j].a;
  81.  
  82. tm3 = 0;
  83. tm2 = 0;
  84. tm1 = 0;
  85. tm0 = 0;
  86.  
  87. for(pil = pir+PI,k = j;pa[k].a < pil && k < n; ++k)
  88. {
  89. if(pa[j].a == pa[k].a)
  90. {
  91. if(pa[k].mark == 1)
  92. {
  93. tm3 ++;
  94. }
  95. else
  96. {
  97. tm2 ++;
  98. }
  99. }
  100. else if(pa[k].mark == 0)
  101. {
  102. tm0++;
  103. }
  104. else
  105. {
  106. tm1++;
  107. }
  108. }
  109. if(pa[0].mark)
  110. tm3++;
  111. else
  112. tm2++;
  113. t1 = tm1+tm2+tm3 + (w-tm0-tm2);
  114. t2 = tm0+tm2+tm3 + (b-tm1-tm3);
  115. if(Max < t1 || Max < t2)
  116. {
  117. Max = t1 > t2 ? t1 : t2;
  118. }
  119. }
  120. }
  121. printf("%d\n",Max);
  122. }
  123. return 0 ;
  124. }

POJ 2280 Amphiphilic Carbon Molecules 极角排序 + 扫描线的更多相关文章

  1. poj2280Amphiphilic Carbon Molecules(极角排序)

    链接 卡了几天的破题,对于hdu的那份数据,这就一神题.. 借助极角排序,枚举以每一个点进行极角排序,然后构造两条扫描线,一个上面一个下面,两条同时走,把上线和下线的点以及上线左边的点分别统计出来,如 ...

  2. UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法

    题目:点击查看题目 思路:这道题的解决思路是极角扫描法.极角扫描法的思想主要是先选择一个点作为基准点,然后求出各点对于该点的相对坐标,同时求出该坐标系下的极角,按照极角对点进行排序.然后选取点与基准点 ...

  3. 【极角排序、扫描线】UVa 1606 - Amphiphilic Carbon Molecules(两亲性分子)

    Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new class of ...

  4. uva 1606 amphiphilic carbon molecules【把缩写写出来,有惊喜】(滑动窗口)——yhx

    Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new classof ...

  5. UVa 1606 (极角排序) Amphiphilic Carbon Molecules

    如果,没有紫书上的翻译的话,我觉得我可能读不懂这道题.=_=|| 题意: 平面上有n个点,不是白点就是黑点.现在要放一条直线,使得直线一侧的白点与另一侧的黑点加起来数目最多.直线上的点可以看作位于直线 ...

  6. UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)

    任意线可以贪心移动到两点上.直接枚举O(n^3),会TLE. 所以采取扫描法,选基准点,然后根据极角或者两两做叉积比较进行排排序,然后扫一遍就好了.旋转的时候在O(1)时间推出下一种情况,总复杂度为O ...

  7. poj 1696 Space Ant (极角排序)

    链接:http://poj.org/problem?id=1696 Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  8. POJ 1696 Space Ant 【极角排序】

    题意:平面上有n个点,一只蚂蚁从最左下角的点出发,只能往逆时针方向走,走过的路线不能交叉,问最多能经过多少个点. 思路:每次都尽量往最外边走,每选取一个点后对剩余的点进行极角排序.(n个点必定能走完, ...

  9. POJ 1696 Space Ant(极角排序)

    Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2489   Accepted: 1567 Descrip ...

随机推荐

  1. win10 下 配置php环境变量

    注意,只需要配置到目录即可:

  2. iOS 七牛多张图片上传

    -(void)uploadImages:(NSArray *)images atIndex:(NSInteger)index token:(NSString *)token uploadManager ...

  3. U盘量产大致研究思路

    这几天搞了一波U盘量产,很多年前玩的基本都是些皮毛,比如U盘分区,U盘启动,以及台电U盘的光驱启动等等,这些现在看起来其实都不入眼,只是简单的将U盘分个区,并且没玩到主控上面去. 下面是一些自己的理解 ...

  4. MSDN WinUSB Example

    The WinUSB user-mode library uses device interface classes to communicate with the kernel-mode USB s ...

  5. PHP 依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI —— Dependency Injection 依赖注入 IoC —— Inversion of Control ...

  6. cocos2d-x学习资源汇总

      http://blog.csdn.net/akof1314 http://blog.csdn.net/bill_man/ http://blog.csdn.net/fylz1125/ MoonWa ...

  7. Delph 两个对立程序使用消息进行控制通信

    在实际应用中,总是会遇到两个独立的程序进行通信,其实通信的方式有好几种,比如进程间通信,消息通信. 项目中用到了此功能, 此功能用于锁屏程序, 下面把实现的流程和大家分享一下. 1. 在锁屏程序中,自 ...

  8. 使用SQL Database Migration Wizard把SQL Server 2008迁移到Windows Azure SQL Database

    本篇体验使用SQL Database Migration Wizard(SQLAzureMW)将SQL Server 2008数据库迁移到 Azure SQL Database.当然,SQLAzure ...

  9. 统计代码执行时间,使用Stopwatch和UserProcessorTime的区别

    当我们需要统计一段代码的执行时间,首先想到的可能是Stopwatch类.在这里,先暂不使用Stopwatch,自定义一个统计代码执行时间的类,大致需要考虑到: 1.确保统计的是当前进程.当前线程中代码 ...

  10. C#编程(二十四)----------修饰符

    修饰符 修饰符即应用于类型或成员的关键字.修饰符可以指定方法的可见性,如public或private,还可以指定一项的本质,如刚发的vritual或abstract. 可见性的修饰符 修饰符 应用于 ...