Description:
小明很喜欢玩大家来找茬的游戏,在游戏中有两张长为L,高为H的长方形图片,图片被切割成L*H个1*1的小正方形,每个小正方形上都画有一个小写英文字母。两张图片相对应的小正方形的字母如果不相同,那么这个小正方形就是一个“茬点”。如果两个相邻小正方形都是“茬点”,那么他们属于同一个“茬区”,两个有共边的小正方形即为相邻。
Input:
输入数据将包含多组图片数据,每组图片数据的第一行有两个正整数H和L,H表示高,L表示长,表示该组图片为L*H个小正方形所组成,如果L和H都为0,表示所有输入到此结束。否则,后面H(1≤H≤100)行数据,每行有L(1≤L≤100)个小写英文字母,再接着H行数据,每行有L个小写英文字母。
Output:
每组图片输出“茬区”的个数,每个“茬区”数占独立的一行。
Sample Input:
1 1ab3 5bababbbabbbababbbbbbbbbbbbbbbb5 5aaaababaababaabbbbabbbaabaaaaaaaaaaaaaaaaaaaaaaaaa0 0
Sample Output:
152
解答:
#include <iostream>
#define N 102
using namespace std;
int a,b,tmp[N][N];
void f(int i,int j)
{
if(tmp[i][j]==0)return;//跳到这个函数唯一的出口
tmp[i][j]=0;
if(i>0) f(i-1,j);
if(j>0) f(i,j-1);
if(i<a-1) f(i+1,j);
if(j<b-1) f(i,j+1);
}
int main()
{int c,i,j;
char m[N][N],n[N][N];
while(cin>>a>>b,a || b)
{ c=0;
for(i=0;i<a;i++)
for(j=0;j<b;j++)
{
cin>>m[i][j];
}
for(i=0;i<a;i++)
for(j=0;j<b;j++)
{
cin>>n[i][j];
}
for(i=0;i<a;i++)
for(j=0;j<b;j++)
{
if(m[i][j]!=n[i][j])
tmp[i][j]=1; //当对应位置不相同时,用1来表示这是一个茬点
}
for(i=0;i<a;i++)
for(j=0;j<b;j++)
{
if(tmp[i][j]==1) c++;
f(i,j);
}
cout<<c<<endl;
}
system("pause");
return 0;
}
心得:void f(int i,int j)这个函数很重要,要加深理解,难点也就在这,它的作用是:当找到一个荐点,要把它周围(即上下左右)均置为0,因为只要与它相邻的位置有一个为1(茬点),则只算作一个荐区。
举个例子当输入为
3 5
babab
bbabb
babab
bbbbb
bbbbb
bbbbb
这一组数据时,tmp数组为
01010
00100
01010
是不是每一个1的上下左右均为0?就是通过这一点来找茬区个数的。于是就有了上面那个f()函数。要理解这个函数,最好的办法是仔细地拿几个数字走几遍,这样就会体会到它是怎么把它的上下左右置为0的(当然还包括这个位置本身)。