POJ1106 (极角排序)

来源:互联网 发布:管家婆网络远程软件 编辑:程序博客网 时间:2024/06/05 21:09

术业有专攻,想练练几何。
题目:给你一个半圆,给你n个点,问半圆最大能覆盖几个点。
题解:第一次做平面几何确实没什么思路,转换一下,先把整个圆外的点给去除,再枚举任意一个点,和圆心连成一条直线,(想像一下如果最优解的直径除了圆心没有经过一个点,你转过去一定角度直至经过一个点是不影响结果的)那么圆就分成两个半圆了,用叉积判断点与直线的位置,取较大值就可以了
还需要考虑如下情况:1、有些点与圆心重合。 2、同时有多个点在一条直线上


#include <iostream>#include <algorithm>#include <queue>#include <stack>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <set>#include <cmath>#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define MOD 1000000007#define fuck() (cout << " ------------------ " << endl)const int maxn = 100000 + 5;using namespace std;struct Point{    double x,y;    Point(){}    Point(double x_, double y_):x(x_),y(y_){}}pt[maxn];bool judge(double x1, double y1, double x2, double y2, double r){    if( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) <= r*r)        return true;    return false;}double cross(Point a, Point b, Point c){    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);}double atleft(Point a, Point b, Point c){    return cross(a,b,c);}int main(){    double cx, cy;    double r;    while(scanf("%lf%lf%lf",&cx,&cy,&r) == 3 && r>0){        int n;        scanf("%d",&n);        int ans = 0;        int cnt = 0;        int sum = 0;        for(int i=0; i<n; i++){            int x, y;            scanf("%d%d",&x,&y);            if(x == cx && y == cy){                ans++;                sum++;                continue;            }            if(judge(x,y,cx,cy,r)){                pt[cnt++] = Point(x,y);            }        }        pt[cnt] = Point(cx,cy);        for(int i=0; i<cnt; i++){            int left = 0;            int right = 0;            for(int j=0; j<cnt; j++){                if(i == j) continue;                double ok = atleft(pt[i],pt[cnt],pt[j]);                if(ok == 0){                    left++;                    right++;                }                else if(ok > 0)                    left++;                else right++;            }            ans = max(ans, sum + left + 1);            ans = max(ans, sum + right + 1);        }        printf("%d\n",ans);    }}
原创粉丝点击