1030B Vasya and Cornfield (幾何)
阿新 • • 發佈:2018-12-24
題目大意:給出兩個整數n,d,代表有一個在第一象限的矩形,座標是(0,d) (d,0) (n,n-d) (n-d,n),再給出一些點的座標,求出這些點是否在矩形中。
題解:只需要判斷該點是否在上下兩條邊和左右兩條邊之間就可以
法①:
判斷一個點是否在兩條線段之間夾著,就轉化成,判斷一個點是否在某條線段的一邊上,就可以利用叉乘的方向性,來判斷夾角是否超過了180度
只要判斷
(向量叉積)
就說明p在邊p1p2和邊p3p4中間夾著,同理也要判斷
#include <bits/stdc++.h> #include <cstring> #define ll long long #define INF 0x3f3f3f3f using namespace std; const double eps = 1e-8; const double PI = acos(-1.0); struct Point { double x,y; Point() {} Point(double _x,double _y) { x = _x; y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } //叉積 double operator ^(const Point &b)const { return x*b.y - y*b.x; } //點積 double operator *(const Point &b)const { return x*b.x + y*b.y; } //繞原點旋轉角度B(弧度值),後x,y的變化 void transXY(double B) { double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); } }; Point p1,p2,p3,p4; double GetCross(Point& p1,Point& p2,Point& p) { return (p2-p1)^(p-p1); } bool pd(Point p) { return GetCross(p1,p2,p) * GetCross(p3,p4,p) >= 0 && GetCross(p2,p3,p) * GetCross(p4,p1,p) >= 0; } int main() { int n,d; cin>>n>>d; p1=Point(0,d); p2=Point(d,0); p3=Point(n,n-d); p4=Point(n-d,n); int T; cin>>T; while(T--) { int x,y; cin>>x>>y; if(pd(Point(x,y))) puts("YES"); else puts("NO"); } return 0; }
法②:
只需要滿足
就是在矩形內
#include <bits/stdc++.h> #include <cstring> #define ll long long #define INF 0x3f3f3f3f using namespace std; int main() { int n,d,T; cin>>n>>d; cin>>T; while(T--) { int x,y; cin>>x>>y; if(x+y>=d && x+y<=2*n-d && x-y>=-d && x-y<=d) puts("YES"); else puts("NO"); } return 0; }