poj 1021 java_POJ 1021 2D-Nim

题意:给你两个图,判定图中由字母组成的区域多边形是否一一对应相等,换句话说,图二与图一中的所有的区域多边形能建立起满射关系。

如果来自两个图的两个多边形全等(可以不位似),即可认为是一一对应了

看到这个题。。很晕。。

借鉴的网上的思路(话说怎么总遇到这种题。。自己想真是想不出好办法。。做题太少了)

对每一个有字母的点,搜索四个方位能相连成线的字母点,把能这样找到的字母总数+1记为这个字母点的value,对于每个图,求出每个点的value,计入一个数组,并排序。

比较两个图的排序数组,完全一样,则说明是等效的图。

这个思路是正确的,但我还没有想出如何能够清楚地写出证明过程,总感觉是个几何推演的问题。

比如说,这两个图的排序数组里面都有相同个数的1,说明有相同个数的孤立点,等价。

有相同个数的2,说明有相同个数的,由两个字母组成的对,等价。(这里头对应的字母点不可能是更大的多边形内的点,因为后者的value必然更大。这是由题意对“构成多边形”的定义所决定的。

以此类推,value的等价就能决定图的等价。

很有趣的思路

代码:

#include

#include

#include

#include

#include

#include

//#define file

#define maxn 10100

using namespace std;

int cas;

int w,h,n;

int map[110][110]= {0};

int node[maxn];

int seq1[maxn],seq2[maxn];

int x[maxn],y[maxn];

int ex,ey;

void work(int s[110][110],int seq[],int xx[],int yy[],int m)

{

for(int i=0; i

{

seq[i]=1;

ex=xx[i];

ey=yy[i];

while(ex

{

seq[i]++;

ex++;

}

ex=xx[i];

ey=yy[i];

while(ex>0&&s[ex-1][ey]==1)

{

seq[i]++;

ex--;

}

ex=xx[i];

ey=yy[i];

while(ey

{

seq[i]++;

ey++;

}

ex=xx[i];

ey=yy[i];

while(ey>0&&s[ex][ey-1]==1)

{

seq[i]++;

ey--;

}

}

}

int main()

{

#ifdef file

freopen("in.txt","r",stdin);

freopen("out.txt","w",stdout);

#endif // file

cin>>cas;

while(cas--)

{

memset(map,0,sizeof(map));

memset(seq1,0,sizeof(seq1));

memset(seq2,0,sizeof(seq2));

cin>>w>>h>>n;

for(int i=0; i

{

scanf("%d%d",&x[i],&y[i]);

map[x[i]][y[i]]=1;

}

work(map,seq1,x,y,n);

memset(map,0,sizeof(map));

for(int i=0; i

{

scanf("%d%d",&x[i],&y[i]);

map[x[i]][y[i]]=1;

}

work(map,seq2,x,y,n);

sort(seq1,seq1+n);

sort(seq2,seq2+n);

bool check=true;

for(int i=0; i

{

if(seq1[i]!=seq2[i])

{

check=false;

break;

}

}

if(check)

{

printf("YES\n");

}

else

{

printf("NO\n");

}

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值