标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7080 Accepted Submission(s): 3041


#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
char input[50][50];
int parent[2500];
bool vis[2500];
int ans,N,M;
int Init()
{
for(int i=(N+1)*(M+1);i>=0;i--)
parent[i]=i;
}
//将字母对应的图案按照上右下左的顺序是否有接口压缩成为二进制对应位是否有1,最高位代表上
int change(char ch)
{
switch(ch)
{
case ‘A‘:return 9;
case ‘B‘:return 12;
case ‘C‘:return 3;
case ‘D‘:return 6;
case ‘E‘:return 10;
case ‘F‘:return 5;
case ‘G‘:return 13;
case ‘H‘:return 11;
case ‘I‘:return 7;
case ‘J‘:return 14;
case ‘K‘:return 15;
}
}
//查找父节点的操作,并做路径压缩
int findP(int x)
{
if(parent[x]==x)
return x;
else
{
parent[x]=findP(parent[x]);
return parent[x];
}
}
void Union(int x,int y)
{
int xp=findP(x),yp=findP(y);
parent[yp]=xp;
return;
}
int main()
{
freopen("in.in","r",stdin);
while(~scanf("%d%d",&N,&M)&&N!=-1)
{
getchar();
Init();
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
scanf("%c",&input[i][j]);
input[i][j]=change(input[i][j]);
//查看这一点是否可以和上相邻联通
if(i>0&&((input[i][j]>>3)&(input[i-1][j]>>1)&1))
{
Union(i*M+j,(i-1)*M+j);
}
//查看这一点是否可以和左相邻联通
if(j>0&&((input[i][j-1]>>2)&input[i][j]&1))
{
Union(i*M+j,i*M+j-1);
}
}
getchar();
}
ans=0;
memset(vis,0,sizeof(vis));
//检查本点父亲是否已被计算过,本点父亲没被计算过说明本点父亲代表的分量需要一个“源“,并修改本点父亲为已经计算过
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
if(!vis[findP(i*M+j)])
{
vis[findP(i*M+j)]=true;
ans++;
}
}
}
cout<<ans<<endl;
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/modengdubai/p/4700531.html