您的位置:首页 > 其它

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

2015-07-31 23:46 573 查看
任意线可以贪心移动到两点上。直接枚举O(n^3),会TLE。

所以采取扫描法,选基准点,然后根据极角或者两两做叉积比较进行排排序,然后扫一遍就好了。旋转的时候在O(1)时间推出下一种情况,总复杂度为O(n^2logN)就可以过了。

另外,本题有个很巧妙的技巧,就是一点等效与相反坐标的相反颜色的点。

第一次写,细节还是蛮多的,花了好久才搞清所有细节。。。

极角排序版,比较容易理解,932ms。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1003;
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<=3) return n;
int ans = -1;
for(int pivot = 0; pivot < n; pivot++){
int k = 0;
for(int i = 0; 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 < 0 || (tmp[k].y == 0 && tmp[k].x < 0) ) {
tmp[k].x = - tmp[k].x; tmp[k].y = -tmp[k].y;
tmp[k].col = P[i].col^1;
}else tmp[k].col = P[i].col;
k++;
}
sort(tmp,tmp+k,cmp);
int w = 0,b = 0;
int i,j;
for(i = 0; i < k; i++) if(tmp[i].col == 0)w++;
for( i = 0; i < k; i = j) {
int lw = 0;
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+1);
ans = max(ans,k-w-b+j-i+1);
w -= lw;
}
}
return ans;
}

int main()
{
int n;
while(~scanf("%d",&n)&&n){
for(int i = 0; i < n; i++)
scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].col);
printf("%d\n",solve(n));
}
return 0;
}


叉积
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: