2019CCPC秦皇島站 A.Angle Beats(hdu 6731)(極角排序)

鏈接

        Angle Beats

題意

        平面上給2000個固有點,點座標範圍-1e9~+1e9,給2000個詢問,每個詢問給個點A,問和給定的2000個固有點能組成多少個直角三角形?

思路

        對於給定點A,如果點A當作直角頂點,直接極角排序,對每個固有點判斷旋轉90°的位置有多少點,累加即可。

        如果A不是直角頂點,應以固有的2000個點爲原點,對其他1999個固有點和A極角排序,當掃到A時判斷垂直方向有多少個固有點。

        但是對於每次詢問都會有O(n*(nlogn+n))的複雜度,在2000個詢問的情況下無疑會TLE。

        所以需要以2000個固有點每一個爲原點,對剩餘點極角排序,遇到詢問點時進行處理。可以消除2000個詢問帶來的影響。

代碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
static const int maxn = 4010;
static const int INF = 0x3f3f3f3f;
static const int mod = (int)1e9 + 7;
static const double eps = 1e-6;
static const double pi = acos(-1);

void redirect(){
    #ifdef LOCAL
        freopen("test.txt","r",stdin);
    #endif
}

inline int sign(const int& x){return x>0?1:(x==0?0:-1);}

struct point{
    int id,x,y;
    point(int x,int y){
        this->x = x,this->y = y;
    }
    point(){}
}p[maxn],q[maxn],o;

point operator-(const point& a,const point& b){
    return point(a.x-b.x,a.y-b.y);
}

bool operator^ (const point& a,const point& b){
    return (1ll*a.x*b.y - 1ll*a.y*b.x) > 0;
}

inline int Quadrant(const point& a){
    if(a.x>0 && a.y>=0)return 1;
    else if(a.x<=0 && a.y>0)return 2;
    else if(a.x<0 && a.y<=0)return 3;
    else if(a.x>=0 && a.y<0)return 4;
}

bool operator< (const point& c,const point& d){
    point a = c-o,b = d-o;
    int qa = Quadrant(a),qb = Quadrant(b);
    if(qa != qb)return qa < qb;
    return a ^ b;
}

int ans[maxn];

int main(){
    redirect();
    int n,m,ma;
    while(~scanf("%d %d",&n,&m)){
        ma = n+m;
        memset(ans,0,sizeof(ans));
        memset(p,0,sizeof(p));
        for(int i = 1;i <= n;i++){
            p[i].id = i;
            scanf("%d %d",&p[i].x,&p[i].y);
            q[i] = p[i];
        }
        for(int i = n+1;i <= ma;i++){
            p[i].id = i;
            scanf("%d %d",&p[i].x,&p[i].y);
            o = p[i];
            sort(p+1,p+1+n);
            for(int j = 1;j <= n;j++){
                int x = p[j].x - o.x,y = p[j].y - o.y;
                point a = point(o.x-y,o.y+x);
                ans[i] += upper_bound(p+1,p+1+n,a) - lower_bound(p+1,p+1+n,a);
            }
        }
        for(int i = 1;i <= n;i++){
            memcpy(p+1,q+1,sizeof(point)*n);
            o = p[i];
            swap(p[i],p[n]);
            sort(p+1,p+n);
            for(int k = n+1;k <= ma;k++){
                int x = p[k].x - o.x,y = p[k].y - o.y;
                point a = point(o.x-y,o.y+x),b = point(o.x+y,o.y-x);
                ans[p[k].id] += upper_bound(p+1,p+n,a) - lower_bound(p+1,p+n,a);
                ans[p[k].id] += upper_bound(p+1,p+n,b) - lower_bound(p+1,p+n,b);
            }
        }
        for(int i = n+1;i <= ma;i++)printf("%d\n",ans[i]);
    }
    return 0;
}

總結

Angel Beats?Angle Beats?

音無結弦之時,天使躍動之心。立於浮華之世,奏響天籟之音。

做出就是金銀,做不出就是廢銅。

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