BZOJ 1199 HNOI 2005 湯姆的遊戲 計算幾何

題目大意

給出若干個圖形,這些圖形中有些是矩形,剩下的是圓形。還有一些點,問每個點在多少個圖形裏面。

思路

題目沒寫數據範圍,其實是25w。敢O(n^2)暴力麼?沒錯這個題就是暴力。只需用二分處理一維座標然後第二維暴力就行了。

CODE

#define _CRT_SECURE_NO_WARNINGS

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 250010
using namespace std;

struct Point{
    double x,y;

    Point(double _,double __):x(_),y(__) {}
    Point() {}
    bool operator <(const Point &a)const {
        return x < a.x;
    }
    void Read() {
        scanf("%lf%lf",&x,&y);
    }
};

inline double Calc(const Point &a,const Point &b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) *(a.y - b.y));
}

struct _Point:Point{
     int id;
}point[MAX];

int ans[MAX];
int graphs,points;

struct Square{
    Point p1,p2;

    void Read() {
        double x1,y1,x2,y2;
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        p1 = Point(min(x1,x2),min(y1,y2));
        p2 = Point(max(x1,x2),max(y1,y2));
    }
    bool InRange(double y) {
        return y > p1.y && y < p2.y;
    }
    void Count() {
        int start = upper_bound(point + 1,point + points + 1,p1) - point;
        int end = lower_bound(point + 1,point + points + 1,p2) - point - 1;
        for(int i = start; i <= end; ++i)
            if(InRange(point[i].y))
                ++ans[point[i].id];
    }
}square[MAX];

struct Circle{
    Point p;
    double r;

    void Read() {
        p.Read();
        scanf("%lf",&r);
    }
    bool InRange(const Point &a) {
        return Calc(a,p) < r;
    }
    void Count() {
        int start = upper_bound(point + 1,point + points + 1,Point(p.x - r,0)) - point;
        int end = lower_bound(point + 1,point + points + 1,Point(p.x + r,0)) - point - 1;
        for(int i = start; i <= end; ++i)
            if(InRange(point[i]))
                ++ans[point[i].id];
    }
}circle[MAX];

int squares,circles;
char s[10];

int main()
{
    cin >> graphs >> points;
    for(int i = 1; i <= graphs; ++i) {
        scanf("%s",s);
        if(s[0] == 'r')
            square[++squares].Read();
        else
            circle[++circles].Read();
    }
    for(int i = 1; i <= points; ++i) {
        point[i].Read();
        point[i].id = i;
    }
    sort(point + 1,point + points + 1);

    for(int i = 1; i <= squares; ++i)
        square[i].Count();
    for(int i = 1; i <= circles; ++i)
        circle[i].Count();

    for(int i = 1; i <= points; ++i)
        printf("%d\n",ans[i]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章