当前位置: 代码迷 >> 综合 >> UVa UVA1606 Amphiphilic Carbon Molecules
  详细解决方案

UVa UVA1606 Amphiphilic Carbon Molecules

热度:49   发布时间:2023-09-23 09:38:54.0

1.任意枚举两个点计算两边黑点加白点最大值

2.任选一个基准点,引一根直线绕着转,计算两边黑点加白点最大值;

对于2,再优化一下,将其他点较基准点的极角排序:

一个小技巧:将黑点关于基准点对称就相当于白点了,于是只要计算直线一边的点的数目最大值就好了

注:当中遇到了一个函数atan2:正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度


#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000+5;
struct point
{int x,y;double rad;bool const operator < (const point& b){return rad<b.rad;}
}op[maxn],p[maxn];int n,color[maxn];bool below180(const point& A,const point& B) //A-O-B <=180° 
{return A.x*B.y - A.y*B.x >=0;
}
int solve()
{if(n<=2) return 2;int ans=0;for(int i=0;i<n;i++)  //op[i]做基准点 {int k=0;for(int j=0;j<n;j++)  //p[k]记录op[j]与op[i]的位置关系 {if(i==j) continue;p[k].x=op[j].x-op[i].x;  //Δxp[k].y=op[j].y-op[i].y;  //Δyif(color[j]) p[k].x=-p[k].x,p[k].y=-p[k].y;  //黑点关于基准点对称 p[k].rad=atan2(p[k].y,p[k].x); k++;}sort(p,p+k);int L=0,R=0,cnt=2; //基准点 + p[L]的那个点 = 2; while(L < k)  //cnt为L~R围住的点的数量,L先不动,R逆时针转180°,没遇到一个点就cnt++; {if(L==R) R=(R+1)%k,cnt++;while(L!=R&&below180(p[L],p[R])) R=(R+1)%k,cnt++;cnt--;   //因为L+1,少了个p[L]点,所以cnt--; L++;ans=max(ans,cnt);}}return ans;
}
int main()
{while(scanf("%d",&n)==1&&n){for(int i=0;i<n;i++)scanf("%d%d%d",&op[i].x,&op[i].y,&color[i]);printf("%d\n",solve());}return 0;
}