1144.农场灌溉问题
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
一农场由图所示的十一种小方块组成,蓝色线条为灌溉渠。若相邻两块的灌溉渠相连则只需一口水井灌溉。
输入
给出若干由字母表示的最大不超过50×50具体由(m,n)表示,的农场图
输出
编程求出最小需要打的井数。每个测例的输出占一行。当M=N=-1时结束程序。
输入样例
2 2 DK HF 3 3 ADC FJK IHE -1 -1
输出样例
2 3
提示
参考迷宫问题,实现时关键要解决好各块的表示问题。
来源
switch 来表示 字母对应一个矩阵
从每个方块的中心点开始深搜
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char a[50][50];
int G[150][150];
int next[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int ans,m,n;
int judge(int x,int y)
{
if(x<0||x>=3*m||y<0||y>=3*n||G[x][y]==1) return 0;
else return 1;
}
void dfs(int x,int y)
{
int i,xn,yn;
if(G[x][y]==0) G[x][y]=1;
for(i=0;i<4;i++)
{
xn=x+next[i][0];
yn=y+next[i][1];
if(judge(xn,yn)) dfs(xn,yn);
}
}
int main()
{
int i,j;
while(scanf("%d%d",&m,&n)!=EOF)
{
ans=0;
if(m==-1&&n==-1) break;
for(i=0;i<m;i++)
scanf("%s",a[i]);
for(i=0;i<m;i++) //下标是从0开始的。
{
for(j=0;j<n;j++)
{
switch(a[i][j])
{
case'A':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1; //==0的地方是有水通的。
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=1;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=1,G[3*i+2][3*j+2]=1;
}break;
case'B':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=1,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=1,G[3*i+2][3*j+2]=1;
}break;
case'C':{
G[3*i][3*j]=1,G[3*i][3*j+1]=1,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=1;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'D':{
G[3*i][3*j]=1,G[3*i][3*j+1]=1,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=1,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'E':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=1,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=1;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'F':{
G[3*i][3*j]=1,G[3*i][3*j+1]=1,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=1,G[3*i+2][3*j+2]=1;
}break;
case'G':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=1,G[3*i+2][3*j+2]=1;
}break;
case'H':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=1;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'I':{
G[3*i][3*j]=1,G[3*i][3*j+1]=1,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'J':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=1,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
case'K':{
G[3*i][3*j]=1,G[3*i][3*j+1]=0,G[3*i][3*j+2]=1;
G[3*i+1][3*j]=0,G[3*i+1][3*j+1]=0,G[3*i+1][3*j+2]=0;
G[3*i+2][3*j]=1,G[3*i+2][3*j+1]=0,G[3*i+2][3*j+2]=1;
}break;
}
}
}
for(i=1;i<3*m;i+=3) //从每个方格的中心点开始枚举。
{
for(j=1;j<3*n;j+=3)
{
if(G[i][j]==0)
{
ans++;
dfs(i,j);
}
}
}
printf("%d\n",ans);
}
return 0;
}