Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long int
- #define ld long double
- #define all(v) v.begin(), v.end()
- #define unq(v) sort(all(v)),(v).resize(unique(all(v))-v.begin())
- #define inf 0x3f3f3f3f
- #define PI acos(-1.0) // 3.1415926535897932
- #define eps 1e-9
- #define radianof(x) x * (PI / 180.0)
- #define degreeof(x) x * (180.0 / PI)
- #define fixdouble(x) cout << fixed << setprecision(x)
- #ifdef ERFANUL007
- #define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
- template < typename Arg1 >
- void __f(const char* name, Arg1&& arg1){
- cout << name << " = " << arg1 << std::endl;
- }
- template < typename Arg1, typename... Args>
- void __f(const char* names, Arg1&& arg1, Args&&... args){
- const char* comma = strchr(names, ',');
- cout.write(names, comma - names) << " = " << arg1 <<" | ";
- __f(comma+1, args...);
- }
- #else
- #define debug(...)
- #endif
- struct PT{
- ll x, y;
- PT(){}
- PT(ll x, ll y) : x(x), y(y) {}
- inline void input() {
- scanf("%lld %lld", &x, &y);
- }
- inline void output() {
- printf("{%lld, %lld}\n", x, y);
- }
- inline bool operator == (const PT &p) const {
- return (abs(x - p.x) < eps && abs(y - p.y) < eps);
- }
- inline bool operator < (const PT &p) const {
- return ((x + eps < p.x) || (abs(x - p.x) < eps && y + eps < p.y));
- }
- } origin = PT(0, 0);
- //-----------operators-----------//
- inline PT operator + (const PT &u, const PT &v) {
- return PT(u.x + v.x, u.y + v.y);
- }
- inline PT operator - (const PT &u, const PT &v) {
- return PT(u.x - v.x, u.y - v.y);
- }
- inline PT operator * (const PT &u, const PT &v) {
- return PT(u.x * v.x - u.y * v.y, u.x * v.y + v.x * u.y);
- } // multiplying two complex numbers
- inline PT operator * (const PT &u, const double &d) {
- return PT(u.x * d, u.y * d);
- }
- inline PT operator * (const double &d, const PT &u) {
- return PT(u.x * d, u.y * d);
- }
- inline PT operator / (const PT &u, const double &d) {
- return PT(u.x / d, u.y / d);
- }
- //---------basic tools---------//
- ll sqnorm(const PT &u) {
- return (u.x * u.x) + (u.y * u.y);
- }
- double norm(const PT &u) {
- return sqrt(sqnorm(u)); // |u|
- }
- PT unit_vector(const PT &u) {
- return (u / norm(u)); // u/|u|
- }
- ll dot(const PT &u, const PT &v) {
- return (u.x * v.x) + (u.y * v.y);
- }
- ll cross(const PT &u, const PT &v) {
- return (u.x * v.y) - (v.x * u.y);
- }
- double angle(const PT &u, const PT &v) { // u.v = |u||v|cos(theta)
- return acos(dot(u, v) / (norm(u) * norm(v)));
- }
- /* r = sqrt(x*x + y*y), theta = atan(y/x) [in radian] */
- PT toPolar(const PT &p){
- return PT(norm(p), atan(p.y/p.x)); // {r, theta}
- }
- /* x = r * cos(theta), y = r * sin(theta) [in radian] */
- PT toCartesian(const PT &p){
- return PT(p.x * cos(p.y), p.x * sin(p.y)); // {x, y}
- }
- PT extend(const PT &u, const PT &v, const double &t) {
- return u + (v - u) * t; // parametric equation
- }
- PT projection(const PT &u, const PT &v, const PT &p) {
- return u + unit_vector(v - u) * (dot(v - u, p - u) / norm(v - u));
- }
- PT rtt(const PT &piv, const PT &u, const double &theta) {
- return (u - piv) * toCartesian(PT(1.0, theta)) + piv;
- }
- //---------being a vector guy---------//
- /* area of Parallelogram abc and d = a+b */
- ll TriArea(const PT &a, const PT &b, const PT &c){
- return cross(b - a, c - a); // + acw, - ccw, 0 linear
- }
- /* line ab to point c */
- int orientation(const PT &a, const PT &b, const PT &c) {
- ll val = (b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y);
- if(val == 0) return 0; // 0 linear
- return val > 0 ? 1 : -1; // + ccw, - acw
- }
- /* point c is on segment ab or not */
- bool isOnSegment(PT a,PT b,PT c){
- if(orientation(a, b, c)) return false;
- return (c.x >= min(a.x, b.x) && c.x <= max(a.x, b.x))
- && (c.y >= min(a.y, b.y) && c.y <= max(a.y, b.y));
- }
- /*line ab and line cd is parallel if ab X cd = 0 */
- bool ifParallel(const PT &a, const PT &b, const PT &c, const PT &d){
- return abs(cross(a - b, c - d)) < eps;
- }
- /*line ab and line cd is perpendicular if ab . cd = 0 */
- bool ifPerpendicular(const PT &a, const PT &b, const PT &c, const PT &d){
- return abs(dot(a - b, c - d)) < eps;
- }
- /* segment ab and segment cd intersect or not */
- bool isSegIntersect(const PT &a, const PT &b, const PT &c, const PT &d){
- return (orientation(a, b, c) != orientation(a, b, d)
- && orientation(c, d, a) != orientation(c, d, b));
- }
- PT _f;
- /* angular sort _f = arr[0] */
- bool CC(const PT &a, const PT &b){
- return (_f.x-a.x)*(_f.y-b.y)<(_f.x-b.x)*(_f.y-a.y);
- }
- bool CCW(PT &a,PT &b){
- return (_f.x-a.x)*(_f.y-b.y)>(_f.x-b.x)*(_f.y-a.y);
- }
- /* Radial Sort: _f = any extreme point of hull */
- bool ClockCmp(const PT &a, const PT &b){
- ll val = orientation(_f, a, b);
- if(val == 0) return sqnorm(a - _f) < sqnorm(b - _f);
- return val > 0;
- }
- bool AClockCmp(const PT &a, const PT &b){
- ll val = orientation(_f, a, b);
- if(val == 0) return sqnorm(a - _f) < sqnorm(b - _f);
- return val < 0;
- }
- //----------------------------------//
- /* receive a list of points and return their concave polygon */
- bool possible; // mark if possible or not
- vector< PT > GrahamScanConcave(vector< PT >& v){
- int n = v.size();
- if(n < 3) return v;
- _f = v[0];
- int pivot = 0;
- for(int i=1; i<v.size(); i++){
- if(v[i].y < _f.y) _f = v[i], pivot = i;
- else if(v[i].y == _f.y && v[i].x < _f.x) _f = v[i], pivot = i;
- }
- swap(v[0], v[pivot]);
- sort(v.begin()+1, v.end(), AClockCmp);
- vector< PT > hull;
- hull.push_back(v[0]); hull.push_back(v[1]);
- for(int i=2; i<n; i++){
- if(orientation(hull[hull.size()-2], hull.back(), v[i])) possible = true;
- hull.push_back(v[i]);
- }
- pivot = n-1;
- for(int i=n-2; i>=0; i--){
- if(orientation(hull[0], hull[pivot], hull[i])) break;
- pivot = i;
- }
- reverse(hull.begin()+pivot, hull.end());
- return hull;
- }
- /* receive a hull v and point a, returns if it is inside or not : Ray Casting algorithm */
- bool PointInPolygonRay(const vector< PT >& v, PT a){
- int n = v.size(), cnt = 0;
- const ll extra = 123456; // must be greater than points abs value
- PT b = PT(a.x + extra, a.y + extra + 1);
- for(int i=0; i<n; i++){
- if(isOnSegment(v[i], v[(i+1)%n], a)) return true;
- if(isSegIntersect(v[i], v[(i+1)%n], a, b)) cnt++;
- }
- return cnt % 2;
- }
- int main()
- {
- #ifdef ERFANUL007
- clock_t tStart = clock();
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- int t, cs=0; scanf("%d", &t);
- while(t--){
- int n;
- scanf("%d", &n);
- vector< PT > hull(n);
- for(int i=0; i<n; i++){
- hull[i].input();
- }
- // hull = GrahamScanConcave(hull);
- printf("Case %d:\n", ++cs);
- int q; scanf("%d", &q);
- while(q--){
- PT a; a.input();
- if(PointInPolygonRay(hull, a)) printf("Yes\n");
- else printf("No\n");
- }
- }
- #ifdef ERFANUL007
- fprintf(stderr, "\n>> Runtime: %.10fs\n", (double) (clock() - tStart) / CLOCKS_PER_SEC);
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement