这道题有两个难点。
第一个难点就是读懂题意,众所周知,poj一般都是,读题两小时,解题五分钟。
题目的意思是一群点上下左右链接就算一个点群,一个点群旋转后依然等于原点群。给你两个图,里面有很多个点群,两个图对应点群一样就算两个图一样,问你这两个图一不一样。
第二个难点就是图的同构问题(“图”指上文中的点群),主要是算图的hash值,hash值一样的就算同一个图,hash值有很多种算法,一种是算每个点到其他点的距离之和,算出来的hash是一个值,不过代码不好实现,另一种是算每个点上下左右能走的距离,算出来的hash值是一个数组(包含n个点),我用的就是第二种算法。
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) x<<1
#define r(x) x<<1|1
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
int mmap[200][200];
int t, w, h, n;
int pos[111111][2];
int mhash[2][5555];
int x, y;
int main() {
cin >> t;
while (t--) {
ms(mhash, 0);
cin >> w >> h >> n;
ms(mmap, 0);
for (int i = 0; i < n; i++) {
cin >> pos[i][0] >> pos[i][1];
mmap[pos[i][0]][pos[i][1]] = 1;
}
for (int i = 0; i < n; i++) {
x = pos[i][0];
y = pos[i][1];
for (int j = x; j < w && mmap[j][y] == 1; j++)
mhash[0][i]++;
for (int j = x; j >= 0 && mmap[j][y] == 1; j--)
mhash[0][i]++;
for (int j = y; j < h && mmap[x][j] == 1; j++)
mhash[0][i]++;
for (int j = y; j >= 0 && mmap[x][j] == 1; j--)
mhash[0][i]++;
}
sort(mhash[0], mhash[0] + n);
ms(mmap, 0);
for (int i = 0; i < n; i++) {
cin >> pos[i][0] >> pos[i][1];
mmap[pos[i][0]][pos[i][1]] = 1;
}
for (int i = 0; i < n; i++) {
x = pos[i][0];
y = pos[i][1];
for (int j = x; j < w && mmap[j][y] == 1; j++)
mhash[1][i]++;
for (int j = x; j >= 0 && mmap[j][y] == 1; j--)
mhash[1][i]++;
for (int j = y; j < h && mmap[x][j] == 1; j++)
mhash[1][i]++;
for (int j = y; j >= 0 && mmap[x][j] == 1; j--)
mhash[1][i]++;
}
sort(mhash[1], mhash[1] + n);
bool flag = true;
for (int i = 0; i < n; i++) {
if (mhash[0][i] != mhash[1][i]) {
flag = false;
break;
}
}
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
不过对于第二种算法,直接用一个int保存所以hash值的和一样能够通过,不知道怎么证明,但我也找不出反例
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) x<<1
#define r(x) x<<1|1
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
int mmap[200][200];
int t, w, h, n;
int pos[111111][2];
int mhash[2];
int x, y;
int main() {
cin >> t;
while (t--) {
ms(mhash, 0);
cin >> w >> h >> n;
ms(mmap, 0);
for (int i = 0; i < n; i++) {
cin >> pos[i][0] >> pos[i][1];
mmap[pos[i][0]][pos[i][1]] = 1;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << mmap[i][j] << " ";
}
cout << endl;
}
for (int i = 0; i < n; i++) {
x = pos[i][0];
y = pos[i][1];
for (int j = x; j < w && mmap[j][y] == 1; j++)
mhash[0]++;
for (int j = x; j >= 0 && mmap[j][y] == 1; j--)
mhash[0]++;
for (int j = y; j < h && mmap[x][j] == 1; j++)
mhash[0]++;
for (int j = y; j >= 0 && mmap[x][j] == 1; j--)
mhash[0]++;
}
ms(mmap, 0);
for (int i = 0; i < n; i++) {
cin >> pos[i][0] >> pos[i][1];
mmap[pos[i][0]][pos[i][1]] = 1;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << mmap[i][j] << " ";
}
cout << endl;
}
for (int i = 0; i < n; i++) {
x = pos[i][0];
y = pos[i][1];
for (int j = x; j < w && mmap[j][y] == 1; j++)
mhash[1]++;
for (int j = x; j >= 0 && mmap[j][y] == 1; j--)
mhash[1]++;
for (int j = y; j < h && mmap[x][j] == 1; j++)
mhash[1]++;
for (int j = y; j >= 0 && mmap[x][j] == 1; j--)
mhash[1]++;
}
if (mhash[0] == mhash[1])
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}