2015
09-17

# Points

A set of integer points on a plane (points whose both cartesian coordinates are integers) which we shall refer to as the pattern, as well as a group of other sets of integer points on the plane are given. We would like to know which of the sets are similar to the pattern, i.e. which of them can be transformed by rotations, translations, reflections and dilations so that they are identical to the pattern.
For instance: the set of points {(0,0), (2,0), (2,1)} is similar to the set {(6,1), (6,5), (4,5)}, it is however not similar to the set {(4,0),(6,0), (5,-1)}.

In the first line there is an integer T (1<=T<=15) – the number of test cases.
For each test case, it begin with a line including a single integer k (1 <= k <= 25000) – the number of points the pattern consists of. In the following k lines there are pairs of integers, separated by single spaces. The i+1st line contains the coordinates of ith point belonging to the pattern: x_i i y_i (-20000 <= x_i, y_i <= 20000). The points forming the pattern are pairwise different. In the next line there is the number of sets to be investigated: n (1 <= n <= 20). Next, there are n descriptions of these sets. The description of each set begins with a line containing a single integer l – the number of points belonging to that particular set (1 <= l <= 25000). These points are described in the following lines, a single point per line. The description of a point consists of two integers separated by a single space – its coordinates x, y (-20000 <= x, y <= 20000). The points which belong to the same set are pairwise different.

In the first line there is an integer T (1<=T<=15) – the number of test cases.
For each test case, it begin with a line including a single integer k (1 <= k <= 25000) – the number of points the pattern consists of. In the following k lines there are pairs of integers, separated by single spaces. The i+1st line contains the coordinates of ith point belonging to the pattern: x_i i y_i (-20000 <= x_i, y_i <= 20000). The points forming the pattern are pairwise different. In the next line there is the number of sets to be investigated: n (1 <= n <= 20). Next, there are n descriptions of these sets. The description of each set begins with a line containing a single integer l – the number of points belonging to that particular set (1 <= l <= 25000). These points are described in the following lines, a single point per line. The description of a point consists of two integers separated by a single space – its coordinates x, y (-20000 <= x, y <= 20000). The points which belong to the same set are pairwise different.

1
3
0 0
2 0
2 1
2
3
4 1
6 5
4 5
3
4 0
6 0
5 -1

[pre]Yes
No

[/pre]

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <functional>
#include <utility>
#include <cstring>
#include <cmath>
#include <complex>
using namespace std;
const int maxn = 25010;
typedef complex<double> point;
#define X real()
#define Y imag()
point p[maxn],s[maxn], tp[maxn],ts[maxn];
double ang;
int cnttp,cntts;
int n,m,M,T;
const double eps = 1e-9;
int sign(double x)
{
if(x>eps)return 1;
if( fabs(x)>eps )return -1;
return 0;
}

bool cmp(const point& p1,const point& p2)
{
if( sign(p1.X-p2.X)==0 ) return ( sign( p1.Y-p2.Y)<0 );
return sign( p1.X-p2.X)<0;
}

double det(const point &p1,const point& p2,const point& org)
{
return (p1.X - org.X) * (p2.Y - org.Y) - (p1.Y - org.Y) * (p2.X - org.X);
}

void graham(int n,point *p,int& s,point *ch)
{
sort(p,p + n,cmp);
int i,s2;
ch[0] = p[0];s = 1;
for(i = 1;i < n;i++) {
while(s > 1 && det(p[i],ch[s - 1],ch[s - 2])<eps)s--;
ch[s++] = p[i];
}
s2 = s;
for(int i = n - 2;i>=0;i--) {
while(s>s2 && det(p[i],ch[s - 1],ch[s - 2])<eps)s--;
ch[s++] = p[i];
}
s--;
}

double getAngle(const point& p1,const point& p2)
{
double dot = p1.X * p2.X + p1.Y * p2.Y;
dot /= abs(p1) * abs(p2);
return dot;
}

bool check(const point& org,const point& trans)
{
for(int i = 0;i<m;i++) {
if(!binary_search(p,p + n,(s[i] - org) * trans + tp[0],cmp))return false;
}
return true;
}

void gao()
{
scanf("%d",&m);
for(int i = 0 ;i<m;i++) {
scanf("%lf%lf",&s[i].X,&s[i].Y);
}
if(n!=m) {puts("No");return;}
if(n<=2){puts("Yes");return;}
graham(m,s,cntts,ts);
double sang;
point org,trans;
point A,B,C;
for(int k=1; k<=2; ++ k){
for(int i = 0;i<m;i++)
s[i].X = -s[i].X;
for(int i = 0;i<cntts;i++)
ts[i].X = -ts[i].X;
for(int i = 0;i<cntts;i++) {
B = ts[i];
A = ts[(cntts + i - 1) % cntts];
C = ts[(i + 1) % cntts];
sang = getAngle(A - B,C - B);
if(fabs(sang - ang)<eps) {
org = B;
trans =  (tp[1] - tp[0]) / (A - B);
if(check(org,trans)) {
puts("Yes");
return;
}
trans = (tp[1] - tp[0]) / (C - B);
if(check(org,trans)) {
puts("Yes");
return;
}
}
}
}
puts("No");
return;
}

int main()
{
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i =0;i<n;i++) {
scanf("%lf%lf", &p[i].X, &p[i].Y);
}
if(n>2) {
graham(n,p,cnttp,tp);
ang = getAngle(tp[1] - tp[0],tp[cnttp - 1] - tp[0]);
}
scanf("%d",&M);
for(int i =0 ;i<M;i++)
gao();
puts("");
}
return 0;
}