hdu 4613 Points<计算几何>

链接: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 }
View Code

 

你可能感兴趣的:(poi)