这个真的很强!网上找的:
唯一的难点是,怎么判断连成一片的棋子形状相同? 一个基于概率的算法是:给每一颗棋子计算一个值,根据这个值是否相等来推测它所在的一片棋子的形状是否相等。计算出每颗棋子的值后对其进行排序,若两副棋盘生成的序列完全相等则推测其等价。
至于这个值如何定,我的设计为:每颗棋子在其水平方向和垂直方向与其相连的棋子总数+1(自己)。比如左图的C,这个值为水平相连2颗(AB)+垂直相连1颗(G)+1=4。
#include <iostream>
using namespace std;
int a[101][101],b[10010],c[10010],d,e,ans,x[10010],y[10010],n,m,k,cas;
int main() {
scanf("%d",&cas);
while (cas--) {
scanf("%d%d%d",&n,&m,&k);
memset(a,0,sizeof(a));
for (int i=1;i<=k;i++) {
scanf("%d%d",&x[i],&y[i]);
a[x[i]][y[i]] = 1;
}
memset(b,0,sizeof(b));
for (int i=1;i<=k;i++) {
b[i] = 1;
d = x[i]; e = y[i];
while (d<n-1 && a[d+1][e]==1) {
b[i]++;
d++;
}
d = x[i]; e = y[i];
while (d>0 && a[d-1][e]==1) {
b[i]++;
d--;
}
d = x[i]; e = y[i];
while (e<m-1 && a[d][e+1]==1) {
b[i]++;
e++;
}
d = x[i]; e = y[i];
while (e>0 && a[d][e-1]==1) {
b[i]++;
e--;
}
}
memset(a,0,sizeof(a));
for (int i=1;i<=k;i++) {
scanf("%d%d",&x[i],&y[i]);
a[x[i]][y[i]] = 1;
}
memset(c,0,sizeof(c));
for (int i=1;i<=k;i++) {
c[i] = 1;
d = x[i]; e = y[i];
while (d<n-1 && a[d+1][e]==1) {
c[i]++;
d++;
}
d = x[i]; e = y[i];
while (d>0 && a[d-1][e]==1) {
c[i]++;
d--;
}
d = x[i]; e = y[i];
while (e<m-1 && a[d][e+1]==1) {
c[i]++;
e++;
}
d = x[i]; e = y[i];
while (e>0 && a[d][e-1]==1) {
c[i]++;
e--;
}
}
sort(b+1,b+k+1);
sort(c+1,c+k+1);
ans = 1;
for (int i=1;i<=k;i++)
if (b[i]!=c[i]) {
ans = 0;
break;
}
if (ans) printf("YES\n");
else printf("NO\n");
}
return 0;
}