UVa UVA1606 Amphiphilic Carbon Molecules

本文介绍了一种通过计算点集中黑白点的最大值来解决最优划分问题的算法。该算法利用了极角排序和基准点旋转的方法,实现了高效的点集划分求解。文中详细解释了算法流程,并附带了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;  //Δx
			p[k].y=op[j].y-op[i].y;  //Δy
			if(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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值