2D-Nim
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct XY
{
int x, y;
XY() {}
XY( int x_, int y_ ) : x(x_), y(y_) {}
bool operator<( const XY &a ) const
{ return x<a.x || x==a.x && y<a.y; }
bool operator==( const XY &a ) const
{ return x==a.x && y==a.y; }
};
vector<vector<XY> > split( vector<XY> p, int W, int H );
bool equal( vector<XY> *b1, vector<XY> *b2 );
void normalize( vector<XY> *c );
void rotate( vector<XY> *c );
void reflect( vector<XY> *c );
int main()
{
int t; cin >> t;
while ( t-- > 0 )
{
int W, H, n;
cin >> W >> H >> n;
vector<vector<XY> > board[2];
for ( int i=0; i<2; i++ )
{
vector<XY> p(n);
for ( int j=0; j<n; j++ )
cin >> p[j].x >> p[j].y;
board[i] = split( p, W, H );
}
bool correct = true;
for ( int i=0; i<(int)board[0].size(); i++ )
{
int j;
for ( j=0; j<(int)board[1].size(); j++ )
if ( equal( &board[0][i], &board[1][j] ) )
break;
if ( j >= (int)board[1].size() )
{
correct = false;
break;
}
board[1].erase( board[1].begin() + j );
}
if ( board[1].size() != 0 )
correct = false;
cout << ( correct ? "YES" : "NO" ) << endl;
}
return 0;
}
vector<vector<XY> > split( vector<XY> p, int W, int H )
{
vector<vector<int> > board( W+2, vector<int>(H+2,-2) );
for ( int i=0; i<(int)p.size(); i++ )
board[p[i].x+1][p[i].y+1] = -1;
vector<vector<XY> > cluster;
for ( int n=0; ; n++ )
{
int x, y;
for ( x=1; x<=W; x++ )
for ( y=1; y<=H; y++ )
if ( board[x][y] == -1 )
goto found;
found:;
if ( x > W )
break;
board[x][y] = n;
cluster.push_back( vector<XY>() );
cluster[n].push_back( XY(x,y) );
bool update;
do
{
update = false;
for ( int x=1; x<=W; x++ )
for ( int y=1; y<=H; y++ )
if ( board[x][y] == -1 )
{
if ( board[x-1][y] == n ||
board[x+1][y] == n ||
board[x][y-1] == n ||
board[x][y+1] == n )
{
board[x][y] = n;
cluster[n].push_back( XY(x,y) );
update = true;
}
}
} while ( update );
}
return cluster;
}
bool equal( vector<XY> *b1, vector<XY> *b2 )
{
for ( int i=0; i<2; i++ )
{
for ( int j=0; j<4; j++ )
{
normalize( b1 );
normalize( b2 );
if ( *b1 == *b2 )
return true;
rotate( b2 );
}
reflect( b2 );
}
return false;
}
void normalize( vector<XY> *c )
{
int mx = INT_MAX;
int my = INT_MAX;
for ( int i=0; i<(int)c->size(); i++ )
mx = min( mx, (*c)[i].x ),
my = min( my, (*c)[i].y );
for ( int i=0; i<(int)c->size(); i++ )
(*c)[i].x -= mx,
(*c)[i].y -= my;
sort( c->begin(), c->end() );
}
void rotate( vector<XY> *c )
{
for ( int i=0; i<(int)c->size(); i++ )
{
int t = (*c)[i].x;
(*c)[i].x = (*c)[i].y;
(*c)[i].y = -t;
}
}
void reflect( vector<XY> *c )
{
for ( int i=0; i<(int)c->size(); i++ )
(*c)[i].x = -(*c)[i].x;
}