从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

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string> #define LL long long
#define EPS (1e-8) using namespace std; const double PI = acos(-1.0); struct P
{
double a;
int x,y,mark;
} pa[1010],p[1010]; double Cal_Angle(P p1,P p2)
{
if(p1.x == p2.x && p1.y == p2.y)
return -100.0;
P v;
v.x = p2.x - p1.x;
v.y = p2.y - p1.y;
if(p1.y <= p2.y)
return acos(v.x/sqrt(v.x*v.x + v.y*v.y));
return 2.0*PI - acos(v.x/sqrt(v.x*v.x + v.y*v.y));
} void Cal_Angle(P p,P *pa,int n)
{
for(int i = 0; i < n; ++i)
{
pa[i].a = Cal_Angle(p,pa[i]);
}
} bool cmp_angle(P p1,P p2)
{
return p1.a < p2.a;
} int main()
{
int n,i,j,k,l,d;
int Max,tl,tr,b,w,s1,s0,s2,s3;
double xm,pil,pir;
P vec;
while(scanf("%d",&n) && n)
{
b = 0;
w = 0;
for(i = 0; i < n; ++i)
{
scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].mark);
pa[i] = p[i];
if(pa[i].mark)
b++;
else
w++;
} Max = -1; for(i = 0; i < n; ++i)
{
Cal_Angle(p[i],pa,n);
sort(pa,pa+n,cmp_angle); pir = pa[1].a;
pil = pir + PI; s1 = s0 = s2 = s3 = 0; for(j = 1; j < n && pa[j].a < pil; ++j)
{
if(pa[j].a == pir)
{
if(pa[j].mark)
s3++;
else
s2++;
}
else
{
if(pa[j].mark)
s1++;
else
s0++;
}
} for(d = j; d < n && pa[d].a == pil; ++d)
{
if(pa[d].mark)
s3++;
else
s2++;
} if(pa[0].mark)
s3++;
else
s2++; tr = s0 + (b-s1)+s2;
tl = s1 + (w-s0)+s3; if(tr > Max || tl > Max)
Max = tr > tl ? tr : tl; k = 1; while(pir < PI && j < n)
{
for(; k < n && pir == pa[k].a; ++k)
{
if(pa[k].mark)
--s3;
else
--s2;
}
pir = pa[k].a;
if(pir > PI)
break;
for(l = k; l < n && pir == pa[l].a; ++l)
{
if(pa[l].mark)
{
++s3;
--s1;
}
else
{
++s2;
--s0;
}
}
for(; j < n && pa[j].a == pil; ++j)
{
if(pa[j].mark)
{
--s3;
++s1;
}
else
{
--s2;
++s0;
}
} pil = pir+PI; for(; j < n && pa[j].a < pil; ++j)
{
if(pa[j].mark)
{
++s1;
}
else
{
++s0;
}
} for(d = j; d < n && pa[d].a == pil ; ++d)
{
if(pa[d].mark)
++s3;
else
++s2;
}
tr = s0 + (b-s1)+s2;
tl = s1 + (w-s0)+s3;
if(tr > Max || tl > Max)
{
Max = tr > tl ? tr : tl;
}
}
}
printf("%d\n",Max);
}
return 0 ;
}

POJ AC_Code 13313MS

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string> #define LL long long
#define EPS (1e-8) using namespace std; const double PI = acos(-1); struct P
{
double x,y,a;
int mark;
}pa[1010],p[1010]; double Cal_Angle(P p1,P p2)
{
if(p1.x == p2.x && p1.y == p2.y)
return -100.0;
P v;
v.x = p2.x - p1.x;
v.y = p2.y - p1.y;
if(p1.y <= p2.y)
return acos(v.x/sqrt(v.x*v.x + v.y*v.y));
return 2.0*PI - acos(v.x/sqrt(v.x*v.x + v.y*v.y));
} void Cal_Angle(P p,P *pa,int n)
{
for(int i = 0;i < n; ++i)
{
pa[i].a = Cal_Angle(p,pa[i]);
}
} bool cmp_angle(P p1,P p2)
{
return p1.a < p2.a;
} int main()
{
int n,i,j,k;
int tm1,tm0,tm2,tm3,Max,t1,t2,b,w;
double xm,pil,pir;
P vec;
while(scanf("%d",&n) && n)
{
b = 0;
w = 0;
for(i = 0;i < n; ++i)
{
scanf("%lf %lf %d",&p[i].x,&p[i].y,&p[i].mark);
pa[i] = p[i];
if(pa[i].mark)
b++;
else
w++;
} Max = -1; for(i = 0;i < n; ++i)
{
Cal_Angle(p[i],pa,n);
sort(pa,pa+n,cmp_angle);
pir = pa[0].a;
j = 1;
while(pir <= PI && j < n)
{
for(;j < n && pa[j].a == pir; ++j)
;
pir = pa[j].a; tm3 = 0;
tm2 = 0;
tm1 = 0;
tm0 = 0; for(pil = pir+PI,k = j;pa[k].a < pil && k < n; ++k)
{
if(pa[j].a == pa[k].a)
{
if(pa[k].mark == 1)
{
tm3 ++;
}
else
{
tm2 ++;
}
}
else if(pa[k].mark == 0)
{
tm0++;
}
else
{
tm1++;
}
}
if(pa[0].mark)
tm3++;
else
tm2++;
t1 = tm1+tm2+tm3 + (w-tm0-tm2);
t2 = tm0+tm2+tm3 + (b-tm1-tm3);
if(Max < t1 || Max < t2)
{
Max = t1 > t2 ? t1 : t2;
}
}
}
printf("%d\n",Max);
}
return 0 ;
}

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. 如何使用PhoneGap打包Web App

    最近做了一款小游戏,定位是移动端访问,思来想去最后选择了jQuery mobile最为框架,制作差不多以后,是否可以打包成App,恰好以前对PhoneGap有耳闻,便想用这个来做打包,可以其中艰辛曲折 ...

  2. bzoj 4000 矩阵快速幂优化DP

    建立矩阵,跑快速幂 /************************************************************** Problem: 4000 User: idy002 ...

  3. pygame系列_font游戏字体_源码下载

    在pygame游戏开发中,一个友好的UI中,漂亮的字体是少不了的 今天就给大伙带来有关pygame中字体的一些介绍说明 首先我们得判断一下我们的pygame中有没有font这个模块 if not py ...

  4. 机器学习算法(5):卷积神经网络原理及其keras实现

    1.原理 CNN的资料特别多,这里不再赘述,仅收集相关的资料供大家参考: a.Deep learning:五十一(CNN的反向求导及练习) b.Deep Learning 2.实现 我们使用keras ...

  5. Ulipad安装、配置使用教程(附Ulipad下载)

    一.安装Ulipad 因为ulipad编辑器使用的是wxpython编写的gui,所以我们需要第三方库wxpython的支持,这里我们先讲一下Ulipad在Windows系统环境下的安装: 1. 确实 ...

  6. 什么是NAS

    个人理解: 1.NAS本身不是一种传输协议,只是一个名词而已,就是一个网络储存. 2.NAS系统本身就是一个Linux,也不是什么发行版,就是在Linux下实现了网络储存. 3.NAS系统里面实现了很 ...

  7. Windows Phone本地数据库(SQLCE):5、[Association]attribute(翻译)(转)

    这是“windows phone mango本地数据库(sqlce)”系列短片文章的第五篇. 为了让你开始在Windows Phone Mango中使用数据库,这一系列短片文章将覆盖所有你需要知道的知 ...

  8. ios7下UISearchBar UITextField 光标不出现的问题

    app支持ios7,在UINavBar 里面加入搜索框,结果光标一直出现不了.在overstackflow网站搜索了一下,竟然有人遇到相同的问题.... 解决办法如下: searchBar.tintC ...

  9. C#编程(十四)----------构造函数

    原文链接:http://blog.csdn.net/shanyongxu/article/details/46501683 构造函数 所谓的构造函数就是和类名重名的且没有返回值的方法. class P ...

  10. ArcGIS 10.2 链接64位Oracle数据库

    https://my.oschina.net/zctzl/blog/909541 来自:https://blog.csdn.net/LoveCarpenter/article/details/5954 ...