POJ 2318 TOYS 计算几何 线段相交

来源:互联网 发布:transparent软件中文版 编辑:程序博客网 时间:2024/04/27 16:29

(x2,y1)和(x,y)形成的一条线段和给出的线段的交点。

http://poj.org/problem?id=2318

#include <map>#include <set>#include <queue>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 4005;const int eps = 1e-8;int sgn(int x) {    if(fabs(x) < eps) return 0;    return x > 0 ? 1 : -1;}struct Point{    int x,y;    Point(){}    Point(int _x,int _y){        x = _x ; y = _y;    }    Point operator + (const Point B) const {        return Point(x+B.x,y+B.y);    }    Point operator - (const Point B) const {        return Point(x-B.x,y-B.y);    }    int operator ^ (const Point B) const {        return x * B.y - y * B.x;    } };int cross(Point a1,Point a2,Point a3){ // >0 a3在a1_a2这条线的左边 <0 右边 =0 三点共线;    return (a2.x-a1.x)*(a3.y-a2.y)-(a3.x-a2.x)*(a2.y-a1.y);}struct Line{    Point s,e;    Line() {}    Line(Point _s,Point _e) {        s = _s ; e = _e ;    }    Line(int x1,int y1,int x2,int y2) {        s = Point(x1,y1); e = Point(x2,y2);    }    bool inter(const Line B) {        return  max(s.x,e.x) >= min(B.s.x,B.e.x) &&                max(B.s.x,B.e.x) >= min(s.x,e.x) &&                max(s.y,e.y) >= min(B.s.y,B.e.y) &&                max(B.s.y,B.e.y) >= min(s.y,e.y) &&    sgn(cross(s,e,B.s))*sgn(cross(s,e,B.e)) <= 0 &&    sgn(cross(B.s,B.e,s))*sgn(cross(B.s,B.e,e)) <= 0 ;    }    void print() {        printf("%d  %d  %d  %d \n",s.x,s.y,e.x,e.y);    }};bool cmp_x_y(Point a1,Point a2) {    if(a1.y == a2.y)        return a1.x < a2.x;    else         return a1.y < a2.y;}int N,M;int my_x1,my_x2,my_y1,my_y2;Line A[5005];Point B[5005];int ans[5005];void input() {    memset(ans,0,sizeof(ans));    scanf("%d",&M);    scanf("%d %d %d %d",&my_x1,&my_y1,&my_x2,&my_y2);    int Ui,Li;    for(int i = 1 ; i <= N ; i++) { //N条线;        scanf("%d %d",&Ui,&Li);        A[i] = Line(Ui,my_y1,Li,my_y2);    }    A[N+1] = Line(my_x2,my_y1,my_x2,my_y2);    int tempx,tempy;    for(int i = 1 ; i <= M ; i++) { //M个点的查询;        scanf("%d %d ",&tempx,&tempy);        B[i] = Point(tempx,tempy);    }}void solve() {    for(int i = 1 ; i <= M ; i++) {        for(int j = 1 ; j <= N + 1; j++) {            if(A[j].inter(Line(Point(my_x1,my_y2),B[i])) == false) {            //if(cross(A[j].s,A[j].e,B[i])<0) {                ans[j-1]++;                break;            }        }    }    for(int i = 0 ; i <= N ; i++) {        printf("%d: %d\n",i,ans[i]);    }}int main(void) {    //freopen("a.in","r",stdin);    int casenum = 0;        while(scanf("%d",&N),N) {        if(casenum++)puts("");        input();        solve();    }}
0 0