Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.
Figure 1
Benny has a map of his farm, which is an array of marks denoting the distribution of water pipes over the whole farm. For example, if he has a map
ADC
FJK
IHE
then the water pipes are distributed like
Figure 2
Several wellsprings are found in the center of some squares, so water can flow along the pipes from one square to another. If water flow crosses one square, the whole farm land in this square is irrigated and will have a good harvest in autumn.
Now Benny wants to know at least how many wellsprings should be found to have the whole farm land irrigated. Can you help him?
Note: In the above example, at least 3 wellsprings are needed, as those red points in Figure 2 show.
题意:
A-K分别代表农田里不同的灌溉管道的铺设形状,输入一个字母矩阵,求这个矩阵农田最少需要多少个水源。
题解:
这个题就是油田问题的变形,还是求连通区域的个数。可以先将A-K的形状在二维数组0,1标记,在输入时转化成数字矩阵,然后就是油田问题的DFS搜索了。
AC代码:
#include<iostream>
using namespace std;
int mapp[200][200];
int n,m;
int xx[4]={-1,1,0,0}; // 四个移动的方向
int yy[4]={0,0,-1,1};
bool check(int x,int y) //检查(x,y)点是否已经搜过了
{
if(x>=0&&x<m*3&&y>=0&&y<n*3&&mapp[x][y])
return true; //前面3个且 是判断是否越界,后面判断是否走过
else return false;
}
void dfs(int x,int y)
{
mapp[x][y]=0; //走到(x,y)点就把它标记了
for(int i=0;i<4;i++)
{
int fx=x+xx[i]; //四个方向移动
int fy=y+yy[i];
if(check(fx,fy))
dfs(fx,fy); //如果(fx,fy)没有走过,就从这个点又开始搜
}
}
int vis[11][9] {{0,1,0,1,1,0,0,0,0},{0,1,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,1,0},{0,0,0,0,1,1,0,1,0},{0,1,0,0,1,0,0,1,0},{0,0,0,1,1,1,0,0,0},{0,1,0,1,1,1,0,0,0},{0,1,0,1,1,0,0,1,0},{0,0,0,1,1,1,0,1,0},{0,1,0,0,1,1,0,1,0},{0,1,0,1,1,1,0,1,0}};
int main() //上面那行就是标记A-K,下标0-10代表A-K,下标0-8是一个字母的3*3矩阵的0,1标记。
{
string ss;
while(cin>>m>>n)
{
if(n==-1&&m==-1) return 0;
for(int i=0; i<m; i++)
{
cin>>ss; //输入一行字母
for(int p=0; p<3; p++) //3*3矩阵的行
{
for(int j=0; j<ss.size(); j++)
{ //遍历一行输入的字母
int t=ss[j]-'A';
for(int q=0; q<3; q++)//3*3矩阵的列
mapp[i*3+p][j*3+q]=vis[t][3*p+q];//下标关系的转换
}
}
}
int ans=0;
for(int i=0;i<m*3;i++)
{
for(int j=0;j<n*3;j++)
{
if(mapp[i][j]) //遍历转换后的数字矩阵,(i,j)为1就DFS,将该点周围的联通点标记为0.
{
ans++;
dfs(i,j);
}
}
}
cout<<ans<<endl;
}
return 0;
}