链接:http://acm.hdu.edu.cn/showproblem.php?pid=4613
题意: 判断一个集合中的点能不能由另一个集合中的点,通过平移,旋转,放缩得到~
思路:先求出集合中的点的凸包,然后枚举每一条边作为起点 ,看原集合中的点能否与要比较的集合中的点一一对应~
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <functional> 5 #include <utility> 6 #include <cstring> 7 #include <cmath> 8 #include <complex> 9 using namespace std; 10 const int maxn = 25010; 11 typedef complex<double> point; 12 #define X real() 13 #define Y imag() 14 point p[maxn],s[maxn], tp[maxn],ts[maxn]; 15 double ang; 16 int cnttp,cntts; 17 int n,m,M,T; 18 const double eps = 1e-9; 19 int sign(double x) 20 { 21 if(x>eps)return 1; 22 if( fabs(x)>eps )return -1; 23 return 0; 24 } 25 26 bool cmp(const point& p1,const point& p2) 27 { 28 if( sign(p1.X-p2.X)==0 ) return ( sign( p1.Y-p2.Y)<0 ); 29 return sign( p1.X-p2.X)<0; 30 } 31 32 double det(const point &p1,const point& p2,const point& org) 33 { 34 return (p1.X - org.X) * (p2.Y - org.Y) - (p1.Y - org.Y) * (p2.X - org.X); 35 } 36 37 void graham(int n,point *p,int& s,point *ch) 38 { 39 sort(p,p + n,cmp); 40 int i,s2; 41 ch[0] = p[0];s = 1; 42 for(i = 1;i < n;i++) { 43 while(s > 1 && det(p[i],ch[s - 1],ch[s - 2])<eps)s--; 44 ch[s++] = p[i]; 45 } 46 s2 = s; 47 for(int i = n - 2;i>=0;i--) { 48 while(s>s2 && det(p[i],ch[s - 1],ch[s - 2])<eps)s--; 49 ch[s++] = p[i]; 50 } 51 s--; 52 } 53 54 double getAngle(const point& p1,const point& p2) 55 { 56 double dot = p1.X * p2.X + p1.Y * p2.Y; 57 dot /= abs(p1) * abs(p2); 58 return dot; 59 } 60 61 bool check(const point& org,const point& trans) 62 { 63 for(int i = 0;i<m;i++) { 64 if(!binary_search(p,p + n,(s[i] - org) * trans + tp[0],cmp))return false; 65 } 66 return true; 67 } 68 69 void gao() 70 { 71 scanf("%d",&m); 72 for(int i = 0 ;i<m;i++) { 73 scanf("%lf%lf",&s[i].X,&s[i].Y); 74 } 75 if(n!=m) {puts("No");return;} 76 if(n<=2){puts("Yes");return;} 77 graham(m,s,cntts,ts); 78 double sang; 79 point org,trans; 80 point A,B,C; 81 for(int k=1; k<=2; ++ k){ 82 for(int i = 0;i<m;i++) 83 s[i].X = -s[i].X; 84 for(int i = 0;i<cntts;i++) 85 ts[i].X = -ts[i].X; 86 for(int i = 0;i<cntts;i++) { 87 B = ts[i]; 88 A = ts[(cntts + i - 1) % cntts]; 89 C = ts[(i + 1) % cntts]; 90 sang = getAngle(A - B,C - B); 91 if(fabs(sang - ang)<eps) { 92 org = B; 93 trans = (tp[1] - tp[0]) / (A - B); 94 if(check(org,trans)) { 95 puts("Yes"); 96 return; 97 } 98 trans = (tp[1] - tp[0]) / (C - B); 99 if(check(org,trans)) { 100 puts("Yes"); 101 return; 102 } 103 } 104 } 105 } 106 puts("No"); 107 return; 108 } 109 110 int main() 111 { 112 scanf("%d",&T); 113 while(T--) { 114 scanf("%d",&n); 115 for(int i =0;i<n;i++) { 116 scanf("%lf%lf", &p[i].X, &p[i].Y); 117 } 118 if(n>2) { 119 graham(n,p,cnttp,tp); 120 ang = getAngle(tp[1] - tp[0],tp[cnttp - 1] - tp[0]); 121 } 122 scanf("%d",&M); 123 for(int i =0 ;i<M;i++) 124 gao(); 125 puts(""); 126 } 127 return 0; 128 }