任意线可以贪心移动到两点上。直接枚举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 两亲性分子 (极角排序或叉积,扫描法)的更多相关文章

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

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

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

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

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

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

  4. UVA - 1606 Amphiphilic Carbon Molecules (计算几何,扫描法)

    平面上给你一些具有黑或白颜色的点,让你设置一个隔板,使得隔板一侧的黑点加上另一侧的白点数最多.隔板上的点可视作任意一侧. 易知一定存在一个隔板穿过两个点且最优,因此可以先固定以一个点为原点,将其他点中 ...

  5. UVA - 1606 Amphiphilic Carbon Molecules(两亲性分子)(扫描法)

    题意:平面上有n(n <= 1000)个点,每个点为白点或者黑点.现在需放置一条隔板,使得隔板一侧的白点数加上另一侧的黑点数总数最大.隔板上的点可以看做是在任意一侧. 分析:枚举每个基准点i,将 ...

  6. UVa 1606 Amphiphilic Carbon Molecules (扫描法+极角排序)

    题意:平面上有 n 个点,每个点不是黑的就是白的,现在要放一个隔板,把它们分成两部分,使得一侧的白点数加上另一侧的黑点数最多. 析:这个题很容易想到的就是暴力,不妨假设隔板至少经过两个点,即使不经过也 ...

  7. UVa 1606 - Amphiphilic Carbon Molecules

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. 【UVa】1606 Amphiphilic Carbon Molecules(计算几何)

    题目 题目 分析 跟着lrj学的,理解了,然而不是很熟,还是发上来供以后复习 代码 #include <bits/stdc++.h> using namespace std; ; stru ...

  9. poj2280--Amphiphilic Carbon Molecules(扫描线+极角排序+转换坐标)

    题目链接:id=2280">点击打开链接 题目大意:给出n个点的坐标.每一个点有一个值0或者1,如今有一个隔板(无限长)去分开着n个点,一側统计0的个数,一側统计1的个数,假设点在板上 ...

随机推荐

  1. sqlserver2012——INTERSECT交查询

    1. select a.成绩编号,a.分数,b.姓名 From 成绩信息 a,学生信息 b ' 一般的查询 a.成绩编号,a.分数,b.姓名 From 成绩信息 a,学生信息 b ' order a. ...

  2. 读取静态Json文件

    创建web项目: string Json = string.Empty; string filePath = Server.MapPath("/***.json");//根目录下的 ...

  3. pandas基础(2)_多重索引

    1:多重索引的构造 >>> #下面显示构造pd.MultiIndex >>> df1=DataFrame(np.random.randint(0,150,size= ...

  4. 51nod1113【矩阵快速幂】

    思路: 裸的矩阵快速幂,读完题,感觉有点对不起四级算法题这一类. #include<bits/stdc++.h> using namespace std; typedef long lon ...

  5. [Xcode 实际操作]六、媒体与动画-(11)UIView视图卷曲动画的制作

    目录:[Swift]Xcode实际操作 本文将演示UIView视图卷曲动画的制作. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit cla ...

  6. Java代码读取文件

    用Java代码读取文件时,保持文件本来的格式(主要是保持换行),这点有时候比较重要.用代码实现也相当简单. private static void readFile() { StringBuilder ...

  7. Javascript中常用方法简介

    Array数组常用方法       先创建一个数组var abc = [1,2,3,4,5,6,7,8,9]; (1)pop(); 这个方法会删除数组的最后一项并返回删除掉的值. 比如:console ...

  8. BZOJ1057(单调栈 or 悬线法)

    方法一 黑白棋盘拥有性质:(r + c) % 2的值决定颜色 因此把某色全部反转,直接求另一色的最大矩形即可,单调栈的经典问题 #include <cstdio> #include < ...

  9. Hive进阶_Hive的表连接

    等值连接 select e.empno, d.deptno from emp e, dept d where e.deptno=d.deptno; 不等值连接 select e.empno, e.en ...

  10. Net Core 2.0生态1

    Net Core 2.0生态 阅读目录 前言:答读者问(time by:2017.8.19) 项目升级到ASP.NET Core 2.0 新增功能:Razor Pages介绍 模板更新 Entity ...