HDU1756 Cupid's Arrow (judging point is inside polygon) Provincial Training 3 Computational Geometry

Cupid’s Arrow

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


Problem Description
Legend has it that there is a Cupid's arrow in the world. Anyone who is shot by this arrow will fall in love with archery.
Countless people in the world have dreamed of getting this arrow. Lele is certainly no exception. But he thought, before he could get this arrow, he had to learn to shoot.
As the days passed, Lele's archery became stronger and stronger. Gradually, he was no longer satisfied with shooting the round target. He began to design various polygonal targets.
However, a new problem has arisen. Due to practicing archery for a long time, Lele's eyesight has become highly short-sighted, and he can't even judge whether his arrow has hit the target or not. So he can only turn to smart Acmers now, can you help him?
 

Input
This question contains multiple sets of tests, please process until the end of the file.
The first line of each set of tests contains a positive integer N (2<N<100), which represents the number of vertices of the target.
Next N lines give the x and y coordinates of the N vertices in a clockwise direction (0<x,y<1000).
Then there is a positive integer M that represents the number of arrows Lele shot.
The next M lines give the X and Y coordinates (0<X,Y<1000) of these arrows shot by Lele, respectively.
 

Output
For each arrow, if Lele hits the target, print "Yes" on one line, otherwise print "No".
 

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

Sample Output
 
  
Yes No


#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
#define maxn 111

struct point {
    double x, y;
    point (double _x = 0, double _y = 0) : x(_x), y(_y) {}
    point operator - (point a) const {
        return point (x-a.x, y-a.y);
    }
    bool operator < (const point &a) const {
        return x < a.x || (x == a.x && y < a.y);
    }
}p[maxn];

const double eps = 1e-10;
int dcmp(double x) {
    if (fabs (x) < eps)
        return 0;
    else return x < 0 ? -1 : 1;
}
double cross (point a, point b) {
    return a.x*b.y-a.y*b.x;
}
double dot (point a, point b) {
    return a.x*b.x + a.y*b.y;
}
bool PointOnLine (point a1, point a2, point p) {//Determine whether point p is on line segment a1a2
    if (dcmp (cross (a1-p, a2-p)) == 0 && dcmp (dot (a1-p, a2-p)) <= 0)
        return 1;
    return 0;
}

int n, m;

bool PointInPolygon (point a, point *b) {
    int w = 0;
    for (int i = 0; i < n; i++) {
        if (PointOnLine (b[i], b[(i+1)%n], a))
            return 0;
        int k = dcmp (cross (b[(i+1)%n]-b[i], a-b[i]));
        int d1 = dcmp (b[i].y - a.y);
        int d2 = dcmp (b[(i+1)%n].y - a.y);
        if (k > 0 && d1 <= 0 && d2 > 0)
            w++;
        if (k < 0 && d2 <= 0 && d1 > 0)
            w--;
    }
    if (w != 0)
        return 1;
    return 0;
}

int main() {
    //freopen ("in", "r", stdin);
    ios::sync_with_stdio(0);
    while (cin >> n) {
        for (int i = 0; i < n; i++) {
            cin >> p[i].x >> p[i].y;
        }
        cin >> m;
        while (m--) {
            point tmp;
            cin >> tmp.x >> tmp.y;
            if (PointInPolygon (tmp, p)) {
                cout << "Yes" << endl;
            }
            else cout << "No" << endl;
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324607007&siteId=291194637