poj2280Amphiphilic Carbon Molecules(极角排序)
卡了几天的破题,对于hdu的那份数据,这就一神题。。
借助极角排序,枚举以每一个点进行极角排序,然后构造两条扫描线,一个上面一个下面,两条同时走,把上线和下线的点以及上线左边的点分别统计出来,如下图
样例3:
假如现在以d为p[0],那么所有可能结果一定是他与其他点的连线所分割的平面,那么首先以de为上线,下线的角度为上线+pi,两条线始终维护着这样的关系。de的下一个点为f,di的下一个点为c ,比较一下两者需要转的角度,选取较小角度转,注意一下相同的时候的处理。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 1010
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
struct point
{
double x,y;
double a;
int flag;
point(double x=,double y = ):x(x),y(y) {}
} p[N],q[N];
int tx[N],ty[N];
typedef point pointt;
point operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return ;
return x<?-:;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double mul(point a,point b,point c)
{
return cross(b-a,c-a);
}
double dis(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
int dot_online_in(point p,point l1,point l2)
{
return !dcmp(mul(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
double Cal_Angle(point p1,point p2)
{
if(p1.x == p2.x && p1.y == p2.y)
return -100.0;
point v;
v.x = p2.x - p1.x;
v.y = p2.y - p1.y;
if(p1.y <= p2.y)
return acos(v.x/sqrt(dot(v,v)));
return 2.0*pi - acos(v.x/sqrt(dot(v,v)));
} void Cal_Angle(point pp,point p[],int n)
{
for(int i = ; i < n; ++i)
{
p[i].a = Cal_Angle(pp,p[i]);
}
}
bool cmp_angle(point p1,point p2)
{
return p1.a < p2.a;
}
int main()
{
int i,j,n;
while(scanf("%d",&n)&&n)
{
int a =,b = ;
for(i = ; i < n; i++)
{
scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].flag);
q[i] = p[i];
if(p[i].flag) a++;
else b++;
}
if(n<)
{
printf("%d\n",n);
continue;
}
int ans = max(a,b);
for(i = ; i < n; i++)
{
swap(q[i],q[]);
for(j = ; j < n; j++)
p[j] = q[j];
Cal_Angle(p[],p,n);
sort(p+,p+n,cmp_angle);
for(j = n-; j > ; j--)
p[j].a-=p[].a;
double ani = p[].a,anj = pi+ani;
int on_red = ,on_blue = ,under_red = , under_blue = ,red = ,blue = ;
int g = ;
while(dcmp(p[g].a-ani)==&&g<n)
{
p[g++].flag?on_red++:on_blue++;
}
int tk = n;
for(j = g; j < n; j++)
{
if(dcmp(p[j].a-anj)>)
{
tk = j;
break;
}
if(dcmp(p[j].a-anj)==)
{
while(dcmp(p[j].a-anj)==&&j<n)
{
p[j++].flag?under_red++:under_blue++;
}
tk = j;
break;
}
p[j].flag?red++:blue++;
}
int ta = ,tb = ;
p[].flag?ta++:tb++; int k1 = red+on_red+under_red++b-blue-tb;
int k2 = blue+on_blue+under_blue++a-red-ta; ans = max(ans,max(k1,k2));
if(g==n) continue; while(tk<n)
{
red+=under_red,blue+=under_blue;
on_red = on_blue = under_blue = under_red = ; if(tk==n||p[tk].a-anj>p[g].a-ani)
{
ani = p[g].a;
anj = ani+pi;
while(dcmp(p[g].a-ani)==&&g<n)
{
p[g].flag?on_red++:on_blue++;
p[g++].flag?red--:blue--;
}
}
else
{
anj = p[tk].a;
ani = anj-pi;
while(dcmp(p[tk].a-anj)==&&tk<n)
{
p[tk++].flag?under_red++:under_blue++;
}
while(dcmp(p[g].a-ani)==&&g<n)
{
p[g].flag?on_red++:on_blue++;
p[g++].flag?red--:blue--;
}
} int k1 = red+on_red+under_red++b-blue-tb;
int k2 = blue+on_blue+under_blue++a-red-ta;
ans = max(ans,max(k1,k2));
}
}
printf("%d\n",ans);
}
return ;
}
poj2280Amphiphilic Carbon Molecules(极角排序)的更多相关文章
- POJ 2280 Amphiphilic Carbon Molecules 极角排序 + 扫描线
从TLE的暴力枚举 到 13313MS的扫描线 再到 1297MS的简化后的扫描线,简直感觉要爽翻啦.然后满怀欣喜的去HDU交了一下,直接又回到了TLE.....泪流满面 虽说HDU的时限是2000 ...
- poj2280--Amphiphilic Carbon Molecules(扫描线+极角排序+转换坐标)
题目链接:id=2280">点击打开链接 题目大意:给出n个点的坐标.每一个点有一个值0或者1,如今有一个隔板(无限长)去分开着n个点,一側统计0的个数,一側统计1的个数,假设点在板上 ...
- UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法
题目:点击查看题目 思路:这道题的解决思路是极角扫描法.极角扫描法的思想主要是先选择一个点作为基准点,然后求出各点对于该点的相对坐标,同时求出该坐标系下的极角,按照极角对点进行排序.然后选取点与基准点 ...
- 【极角排序、扫描线】UVa 1606 - Amphiphilic Carbon Molecules(两亲性分子)
Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new class of ...
- UVa 1606 (极角排序) Amphiphilic Carbon Molecules
如果,没有紫书上的翻译的话,我觉得我可能读不懂这道题.=_=|| 题意: 平面上有n个点,不是白点就是黑点.现在要放一条直线,使得直线一侧的白点与另一侧的黑点加起来数目最多.直线上的点可以看作位于直线 ...
- UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
任意线可以贪心移动到两点上.直接枚举O(n^3),会TLE. 所以采取扫描法,选基准点,然后根据极角或者两两做叉积比较进行排排序,然后扫一遍就好了.旋转的时候在O(1)时间推出下一种情况,总复杂度为O ...
- uva 1606 amphiphilic carbon molecules【把缩写写出来,有惊喜】(滑动窗口)——yhx
Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new classof ...
- POJ 1696 Space Ant 【极角排序】
题意:平面上有n个点,一只蚂蚁从最左下角的点出发,只能往逆时针方向走,走过的路线不能交叉,问最多能经过多少个点. 思路:每次都尽量往最外边走,每选取一个点后对剩余的点进行极角排序.(n个点必定能走完, ...
- Space Ant---poj1696(极角排序)
题目链接:http://poj.org/problem?id=1696 题意:给你n个点,然后我们用一条线把它们连起来,形成螺旋状: 首先找到左下方的一个点作为起点,然后以它为原点进行极角排序,找到极 ...
随机推荐
- python中raw_input输入数字问题
如果按照下面方式,则无论你输入什么,都会打印12,因为raw_input接受的输入是按照字符串处理的 num = raw_input('please enter a num:') if num > ...
- Git: untrack a file in local repo only and keep it in the remote repo
You could update your index: git update-index --assume-unchanged nbproject/project.properties and ma ...
- Wordpress基础:精简头部wp_head
在Wordpress里 <?php wp_head(); ?> wp_head()是一个重要的函数,它允许插件开发者向你的站点动态地添加CSS和javascript,如果我们不在模板中引入 ...
- Java学习-001-JDK安装配置
本节主要讲述在 Win7 64bit 系统下安装.配置 JDK8u25,敬请参阅.详细步骤如下: 一.JDK下载 您可到 官方网站 或 我的云盘 下载,对应的JDK8u25的安装程序,下载过程不再赘述 ...
- Windwos服务器远程桌面不能复制粘贴的解决方法
今天使用远程桌面连接登陆服务器,发现不能在本地电脑和远程服务器之间复制粘贴文件了,复制粘贴文本也不行. 网上搜了一下,主要有两种情况: 1.复制粘贴功能原本可以用,突然失灵了2.从头到尾都无法使用这个 ...
- JAVA邮件发送的简单实现
JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件.这一机制被广泛的用在注 ...
- Ubantu16.4的安装过程以及基本配置
Ubantu16.4的安装过程以及基本配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入高级运维工程师之路:598432640 其实很早以前就听朋友说ubantu这怎么好 ...
- overflow:hidden---清除浮动,隐藏溢出
overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解.一提到清除浮动,我们就会想到另外一个CSS样式: ...
- Zju1015 Fishing Net
弦图判定 代码 #include<cstdio> #include<queue> #define mp make_pair #define fi first #define s ...
- jsp 环境配置记录
1. jdk,下载地址1 环境变量配置: 1)新建 JAVA_HOME 变量 . 变量值填写jdk的安装目录(本人是 C:\Java\jdk1.7.0) 2) 系统变量→寻找 Path 变量→编辑 ...