UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
任意线可以贪心移动到两点上。直接枚举O(n^3),会TLE。
所以采取扫描法,选基准点,然后根据极角或者两两做叉积比较进行排排序,然后扫一遍就好了。旋转的时候在O(1)时间推出下一种情况,总复杂度为O(n^2logN)就可以过了。
另外,本题有个很巧妙的技巧,就是一点等效与相反坐标的相反颜色的点。
第一次写,细节还是蛮多的,花了好久才搞清所有细节。。。
极角排序版,比较容易理解,932ms。
#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
struct Point
{
int x,y;
double rad;
bool operator<(const Point &rhs) const {
return rad < rhs.rad;
}
}P[maxn];
int col[maxn]; Point tmp[maxn]; bool cmp(const Point& a,const Point& b) //anticlockwise sort
{
return a.x*b.y >= b.x*a.y;
} int solve(int n)
{
if(n<=) return n;
int ans = -;
for(int pivot = ; pivot < n; pivot++){
int k = ;
for(int i = ; i < n; i++) if(i!=pivot){
tmp[k].x = P[i].x - P[pivot].x;
tmp[k].y = P[i].y - P[pivot].y;
if(col[i]) { tmp[k].x = - tmp[k].x; tmp[k].y = -tmp[k].y; }
tmp[k].rad = atan2(tmp[k].y, tmp[k].x);
k++;
}
sort(tmp,tmp+k);
int L = , R = , sum = ;
while(L<k){
if(L == R) { R = (R+)%k; sum++; }
while(R != L && cmp(tmp[L],tmp[R])) {
R = (R+)%k; sum++;
}
ans = max(ans,sum);
sum--; L++;
}
}
return ans;
} int main()
{
int n;
while(~scanf("%d",&n)&&n){
for(int i = ; i < n; i++)
scanf("%d%d%d",&P[i].x,&P[i].y,col+i);
printf("%d\n",solve(n));
}
return ;
}
极角排序
如果卡精度,那么就用叉积两两比较,算极角常数大一些,叉积跑的快一点577ms。
#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
struct Point
{
int x,y,col;
}P[maxn],tmp[maxn];; inline int cross(const Point& a,const Point& b)
{
return a.x*b.y - b.x*a.y;
} bool cmp(const Point& a,const Point& b) //anticlockwise sort
{
return a.x*b.y > b.x*a.y;
} int solve(int n)
{
if(n<=) return n;
int ans = -;
for(int pivot = ; pivot < n; pivot++){
int k = ;
for(int i = ; i < n; i++) if(i!=pivot){
tmp[k].x = P[i].x - P[pivot].x;
tmp[k].y = P[i].y - P[pivot].y;
if(tmp[k].y < || (tmp[k].y == && tmp[k].x < ) ) {
tmp[k].x = - tmp[k].x; tmp[k].y = -tmp[k].y;
tmp[k].col = P[i].col^;
}else tmp[k].col = P[i].col;
k++;
}
sort(tmp,tmp+k,cmp);
int w = ,b = ;
int i,j;
for(i = ; i < k; i++) if(tmp[i].col == )w++;
for( i = ; i < k; i = j) {
int lw = ;
for(j = i; j < k; j++) {
if(cross(tmp[i],tmp[j])) break;
if(tmp[j].col) b++;
else lw++;
}
ans = max(ans,w+b+);
ans = max(ans,k-w-b+j-i+);
w -= lw;
}
}
return ans;
} int main()
{
int n;
while(~scanf("%d",&n)&&n){
for(int i = ; i < n; i++)
scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].col);
printf("%d\n",solve(n));
}
return ;
}
叉积
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【把缩写写出来,有惊喜】(滑动窗口)——yhx
Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new classof ...
- UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法
题目:点击查看题目 思路:这道题的解决思路是极角扫描法.极角扫描法的思想主要是先选择一个点作为基准点,然后求出各点对于该点的相对坐标,同时求出该坐标系下的极角,按照极角对点进行排序.然后选取点与基准点 ...
- UVA - 1606 Amphiphilic Carbon Molecules (计算几何,扫描法)
平面上给你一些具有黑或白颜色的点,让你设置一个隔板,使得隔板一侧的黑点加上另一侧的白点数最多.隔板上的点可视作任意一侧. 易知一定存在一个隔板穿过两个点且最优,因此可以先固定以一个点为原点,将其他点中 ...
- UVA - 1606 Amphiphilic Carbon Molecules(两亲性分子)(扫描法)
题意:平面上有n(n <= 1000)个点,每个点为白点或者黑点.现在需放置一条隔板,使得隔板一侧的白点数加上另一侧的黑点数总数最大.隔板上的点可以看做是在任意一侧. 分析:枚举每个基准点i,将 ...
- UVa 1606 Amphiphilic Carbon Molecules (扫描法+极角排序)
题意:平面上有 n 个点,每个点不是黑的就是白的,现在要放一个隔板,把它们分成两部分,使得一侧的白点数加上另一侧的黑点数最多. 析:这个题很容易想到的就是暴力,不妨假设隔板至少经过两个点,即使不经过也 ...
- UVa 1606 - Amphiphilic Carbon Molecules
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 【UVa】1606 Amphiphilic Carbon Molecules(计算几何)
题目 题目 分析 跟着lrj学的,理解了,然而不是很熟,还是发上来供以后复习 代码 #include <bits/stdc++.h> using namespace std; ; stru ...
- poj2280--Amphiphilic Carbon Molecules(扫描线+极角排序+转换坐标)
题目链接:id=2280">点击打开链接 题目大意:给出n个点的坐标.每一个点有一个值0或者1,如今有一个隔板(无限长)去分开着n个点,一側统计0的个数,一側统计1的个数,假设点在板上 ...
随机推荐
- 使用go实现基于命令行的计算器程序
项目目录结构 calcs.go源文件 package main import ( "fmt" "os" "strconv" "my ...
- Ajax的调试错误信息的输出
error: function(xhr, status, error) { console.log(xhr); console.log(status); console.log(error); }
- Linux下的eclipse的安装
其实在linux里配好java环境后,就已经好了. 从官网下一个eclipse,解压后,就可以直接执行eclipse了,实在是不知道什么是安装. 其实在配置java时,也是一样. 可见在linux下, ...
- WPF在ViewModel中绑定按钮点击(CommandBase定义)
定义CommandBase public class CommandBase:ICommand { private readonly Action<object> _commandpara ...
- Python学习笔记(socket)
socket(数据传输接口) 搭建服务端 1.导入模块 import socket 2.创建socket对象 sock=socket .socket(socket_family,socket_topy ...
- python 之 软件开发目录规范 、logging模块
6.4 软件开发目录规范 软件(例如:ATM)目录应该包含: 文件名 存放 备注 bin start.py,用于起动程序 core src.py,程序核心功能代码 conf settings. ...
- 77%的Linux运维都不懂的内核问题
前言 之前在实习时,听了 OOM 的分享之后,就对 Linux 内核内存管理充满兴趣,但是这块知识非常庞大,没有一定积累,不敢写下,担心误人子弟,所以经过一个一段时间的积累,对内核内存有一定了解之后, ...
- Python小世界:彻底搞懂Python一切皆对象!!!
前言 犹记得当初学习Python的时候,对于Python一切皆对象很是懵逼,因为Python是面向对象的动态型语言,而在函数及高阶函数的应用中,如若对于一切皆对象不是有很透彻的了解,基础不是那么牢固的 ...
- js new Date("2016-07-01 08:00:00") 格式在IE内核浏览器中显示NaN的问题
js new Date("2016-07-01 08:00:00") 格式在IE内核浏览器中显示NaN的问题 废话就不多了,var dd = new Date("2016 ...
- 微信小程序采坑之上拉触底加载更多和下拉刷新
小程序中加载更多数据一般都是触底刷新 有自带的函数: onReachBottom: function (){} 但是在使用时触发完全没有反应,后来尝试给外层加了一个高度,解决问题 仔细想想也是,没有设 ...