hdu 1756 Cupid's Arrow(点在多边形内)

Cupid's Arrow

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1037    Accepted Submission(s): 385


Problem Description
传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?
 

Input
本题目包含多组测试,请处理到文件结束。
在每组测试的第一行,包含一个正整数N(2 接着N行按顺时针方向给出这N个顶点的x和y坐标(0 然后有一个正整数M,表示Lele射的箭的数目。
接下来M行分别给出Lele射的这些箭的X,Y坐标(0
 

Output
对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。
 

Sample Input
 
   
4 10 10 20 10 20 5 10 5 2 15 8 25 8
 

Sample Output
 
   
Yes No
 

Author
linle

题意:天朝文字

题解:很久之前做得题目,突然想起来判点在多边形内的代码很多做法是错的,于是就贴一个代码出啦回忆一下


#include 
#include 
#include 
#include 

using namespace std;

struct point{
    double x, y;
    void input(){ scanf("%lf%lf", &x, &y); }
    point(double x_ = 0, double y_ = 0): x(x_), y(y_){}
}p[108];

const int offset = 1008;
const double eps = 1e-8;
int n;

double cross(point p1, point p2, point p3){
    return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
}

int sign(double x){
    if(x < -eps) return -1;
    else if(x > eps) return 1;
    return 0;
}

int onsegment(point p1, point p2, point p3){
    if(p1.x < min(p2.x, p3.x) || p1.x > max(p2.x, p3.x)) return 0;
    if(p1.y < min(p2.y, p3.y) || p1.y > max(p2.y, p3.y)) return 0;
    if(sign(cross(p1, p2, p3))) return 0;
    return 1;
}

int intersect(point p1, point p2, point p3, point p4){
    if(cross(p1, p2, p3) * cross(p1, p2, p4) > eps) return 0;
    if(cross(p3, p4, p1) * cross(p3, p4, p2) > eps) return 0;
    return 1;
}

int inpolygon(point p1){
    int cou, i = 0;

    p[n] = p[0];
    while(i < n){
        point p2 = point(rand()%1000+offset, rand()%1000+offset);
        for(i = cou = 0; i < n; i++){
            if(onsegment(p1, p[i], p[i+1])) return 1;
            if(!sign(cross(p1, p2, p[i]))) break;
            if(intersect(p1, p2, p[i], p[i+1])) cou++;
        }
    }

    return cou & 1;
}

int main(){
    int q;

    srand((unsigned)time(NULL));
    while(scanf("%d", &n) > 0){
        for(int i = 0; i < n; i++) p[i].input();
        scanf("%d", &q);
        while(q--){
            p[103].input();
            if(inpolygon(p[103])) printf("Yes\n");
            else printf("No\n");
        }
    }

    return 0;
}



你可能感兴趣的:(ACM之路(c/c++),计算几何)