http://codeforces.com/gym/101484/problem/E
题解 凸包板题
#define _CRT_SECURE_NO_WARNINGS #include<cmath> #include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> #include<vector> using namespace std; #define rep(i,t,n) for(int i =(t);i<=(n);++i) #define per(i,n,t) for(int i =(n);i>=(t);--i) #define mmm(a,b) memset(a,b,sizeof(a)) const int maxn = 2e5 + 10; int a[maxn]; typedef long long ll; const double eps = 1e-7;//eps用于控制精度 struct Point//点或向量 { double x, y; Point() {} Point(double x, double y) :x(x), y(y) {} }; bool cmp1(Point a,Point b){ if(a.x==b.x)return a.y<b.y; else return a.x<b.x; } struct triVec { double x, y,z; triVec() {} triVec(double x, double y,double z) :x(x), y(y),z(z) {} }; typedef Point Vector; Vector operator + (Vector a, Vector b)//向量加法 { return Vector(a.x + b.x, a.y + b.y); } Vector operator - (Vector a, Vector b)//向量减法 { return Vector(a.x - b.x, a.y - b.y); } Vector operator * (Vector a, double p)//向量数乘 { return Vector(a.x*p, a.y*p); } Vector operator / (Vector a, double p)//向量数除 { return Vector(a.x / p, a.y / p); } int dcmp(double x)//精度三态函数(>0,<0,=0) { if (fabs(x) < eps)return 0; else if (x > 0)return 1; return -1; } bool operator == (const Point &a, const Point &b)//向量相等 { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } double Dot(Vector a, Vector b)//内积 { return a.x*b.x + a.y*b.y; } double Length(Vector a)//模 { return sqrt(Dot(a, a)); } Vector Rotate(Vector a, double rad)//逆时针旋转 { return Vector(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad)); } double Cross(Vector a, Vector b)//外积 { return a.x*b.y - a.y*b.x; } double Distance(Point a, Point b)//两点间距离 { return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); } int n, m; double z; //Point p[maxn]; Point f1[maxn]; Point f2[maxn]; Point result[maxn]; vector<Point> P; int top; bool cmp(Point A, Point B) { double ans = Cross(A - P[0], B - P[0]); if (dcmp(ans) == 0) return dcmp(Distance(P[0], A) - Distance(P[0], B)) < 0; else return ans > 0; } void Graham()//Graham凸包扫描算法 { for (int i = 1; i < P.size(); i++)//寻找起点 if (P[i].y < P[0].y || (dcmp(P[i].y - P[0].y) == 0 && P[i].x < P[0].x)) swap(P[i], P[0]); sort(P.begin()+1, P.end(), cmp);//极角排序,中心为起点 result[0] = P[0]; result[1] = P[1]; top = 1; for (int i = 2; i < P.size(); i++) { while (Cross(result[top] - result[top - 1], P[i] - result[top - 1]) < 0 && top >= 1) top--; result[++top] = P[i]; } } int main() { int n,m; cin>>n>>m; rep(i,1,n){scanf("%lf%lf",&f1[i].x,&f1[i].y);P.push_back(f1[i]);} rep(i,1,m){scanf("%lf%lf",&f2[i].x,&f2[i].y);P.push_back(f2[i]);} //if(n<=2||m<=2) return 0*printf("NO "); Graham(); sort(result,result+top,cmp); sort(f1+1,f1+n+1,cmp); sort(f2+1,f2+n+1,cmp); int f=1,ff=1; rep(i,1,n){ if(!(f1[i]==result[i-1]))f=0; } if(n!=top+1)f=0; rep(i,1,m){ if(!(f2[i]==result[i-1]))ff=0; } if(m!=top+1)f=0; /* rep(i,1,n)cout<<f1[i].x<<'*'<<f1[i].y<<' '; cout<<endl; rep(i,1,m)cout<<f2[i].x<<'*'<<f2[i].y<<' '; cout<<endl; rep(i,0,top)cout<<result[i].x<<'*'<<result[i].y<<' '; cout<<endl;*/ if(f|ff)puts("YES"); else puts("NO"); }