POJ 2280 幾何題 經典 枚舉+極角排序+旋轉掃描

枚舉每個點做旋轉點,按照極角排序,掃描一次,得出結果.


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define PI 3.14159265359
#define eps 1e-8
using namespace std;
struct Point
{
    int x,y,r;
    double ang;
} rem[1005],v[1005];
int n;
int cmp(const struct Point a,const struct Point b)  //按角度排序(極角排序)
{
    if (a.ang < b.ang)
        return 1;
    else return 0;
}
int sig(double a)   //判斷當前是否滿足精度  0滿足 1不滿足 -1等於精度
{
    if (fabs(a) < eps)
        return 0;
    else if (a > 0)
        return 1;
    else return -1;
}
int cross(struct Point a,struct Point b,struct Point c)   //叉積
{
    return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
int main()
{
    while (scanf("%d",&n) && n)
    {
        int ans = 0;
        for (int i = 1; i <= n; ++i)   
        {
            scanf("%d%d%d",&v[i].x,&v[i].y, &v[i].r);
            rem[i] = v[i];  //rem 存放最原始的數據
        }
        for (int i = 1; i <= n; ++i)    //****枚舉每個點做旋轉點
        {
            for (int j = 1; j <= n; ++j)  //對v賦值 對於屬性是0的點,直接賦值,屬性爲1的點,對稱賦值. 並計算角度
            {
                v[j] = rem[j];
                if (v[j].r == 1)  //如果是屬性是1的點 對稱到 直線的 另一端
                {
                    v[j].x = rem[i].x * 2 - v[j].x;
                    v[j].y = rem[i].y * 2 - v[j].y;
                }
                v[j].ang = atan2(v[j].y - rem[i].y , v[j].x - rem[i].x);  //計算弧度
            }
            swap(v[i],v[1]); //v[1]總是當前枚舉的點  所以不斷的交換v[i] 值與v[1]值
            sort(v + 2, v + n + 1, cmp);  //****極角排序
  
            //開始點,已經有2個,v[1]和v[2] 然後對第三個點進行考慮
            for(int s = 2,t = 3; s <= n && sig(v[s].ang) <= 0; s++) //****當前直線由v[1]和v[s]兩點確定(選取直線,旋轉掃描)
            {
                int on = 2;  //on是直線上點的個數
                for ( ; t <= n && cross(v[1],v[s],v[t]) >= 0; t++) //只判斷一側的點,t統計的是在一側的點
                {
                    if (cross(v[1],v[s],v[t]) == 0)  //三點共線  在icpc線上
                        on++;  //線上點+1
                }
                //t-s-1:0側溶解0,1側溶解0的情況能得到的值 n-(t-s+1)+on 0側溶解1,1側溶解0
                ans = max(ans , max(t - s + 1, n - (t - s + 1) + on));
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章