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;
}

你可能感兴趣的:(计算几何,bzoj,HNOI2005)