1606 - Amphiphilic Carbon Molecules(极角排序)

这道题的关键是用到了极角排序的方法,枚举一个固定点,其他点以此点为原心求出角度,然后排序,将数点的多少转化为数角度的多少。因为角度是有序的,便可以用一次扫描求出最大值。另外,还用到了一个小技巧,那就是利用对称性,将一侧的黑点转化成另一侧的白点,这样只需要数白点的个数就好了。

值得注意的是,为了形成那条分界线,我们枚举两个角度(也就是由基准点为原心的新坐标系中的点)   ,使他们之间的夹角不超过180°,为了使分界线旋转360°,我们将l变量枚举到最后一个点再停,所以r变量的自加变成了(r+1)%cnt


如图,由于已经将黑点对称变换到另一侧,所以这个锐角范围内的点的个数就是答案。这相当于一个并不直的挡板。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 5;
int n;
struct point{
    int x,y,col;
    double rad;
    bool operator < (const point &r) const {
        return rad < r.rad;
    }
}p[maxn],op[maxn];
bool X(int l,int r){
    return p[l].x*p[r].y-p[l].y*p[r].x >= 0 ;
}
int main(){
    while(~scanf("%d",&n)&&n){
        for(int i=0;i<n;i++) scanf("%d%d%d",&op[i].y,&op[i].x,&op[i].col);
        if(n<=2)  { printf("%d",n) ; continue; }
        int ans = 0;
        for(int i=0;i<n;i++) {
            int cnt = 0;
            for(int j=0;j<n;j++){
                if(i!=j) {
                    p[cnt].x = op[j].x - op[i].x;
                    p[cnt].y = op[j].y - op[i].y;
                    if(op[j].col == 1) {
                        p[cnt].x = -p[cnt].x;
                        p[cnt].y = -p[cnt].y;
                    }
                    p[cnt].rad = atan2(p[cnt].y,p[cnt].x);
                    cnt++;
                }
            }
            sort(p,p+cnt);

            int sum = 2,l = 0,r = 0;
            while(l < cnt){
                if(l==r) { r = (r+1)%cnt; sum++; }  //为了枚举360°
                while(l!=r&&X(l,r)) {
                    r = (r+1)%cnt; sum++; 
                }
                l++; //当超过180°时,
                sum--;//减掉不在锐角内的点
                ans = max(ans,sum);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值