Amphiphilic Carbon Molecules UVA - 1606(扫描线+极角排序)

题意

给你一个平面上的n个点,有白点与黑点,问你怎么插入一个隔板使得隔板左右的黑白点数相加值最大。

思路

我们让隔板至少经过两个点,因为隔壁上的点属于左右两边的点,所以我们可以这么操作。我们枚举每个点,对于其他点建立与这个点的相对坐标,然后极角排序一发,接着就是枚举每两个点设置隔板,求隔板两边的黑白点数了。朴素的做法是我们设i为基准点,l为与i形成隔板的点,r为旋转点,我们让i与l不动,旋转r,旋转360度之后,就能求出黑白点了,然后取个max,接下来就是让l++,然后r又从l这个点开始继续旋转。

当然这里的优化很牛逼,首先我们将黑点对着基准点做中心对称,这样我们让r旋转180度的时候扫过的所有的点不就是分布在隔板两边的黑白点的和嘛!然后我们让l++,这时候r不需要再l进行扫描而是从原来的r继续旋转就可以了,这一点有点类似与移动一个区间!类似于尺取法。

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;
int n;
const int MAXN=1000+5;
struct Point{
    int x,y,col;
    double angle;
}p[MAXN],p2[MAXN];

bool cmp(Point a,Point b)
{
    return a.angle<b.angle;
}

bool cross(Point a,Point b)
{
    return a.x*b.y-a.y*b.x>=0;
}
int main()
{
    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);
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int k=0;
            for(int j=0;j<n;j++)
            {
                if(i==j) continue;
                p2[k].x=p[j].x-p[i].x;
                p2[k].y=p[j].y-p[i].y;
                p2[k].col=p[j].col;
                if(p2[k].col) p2[k].x=-p2[k].x,p2[k].y=-p2[k].y;
                p2[k].angle=atan2(p2[k].y,p2[k].x);
                k++;
            }
            sort(p2,p2+k,cmp);
            int l=0,r=0,cont=2;
            while(l<k)
            {
                if(l==r) {r=(r+1)%k,cont++;}
                while(l!=r&&cross(p2[l],p2[r]))
                {
                    r=(r+1)%k;
                    cont++;
                }  
                cont--;
                ans=max(ans,cont);
                l++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值