题目:
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
一农场由图所示的十一种小方块组成,蓝色线条为灌溉渠。若相邻两块的灌溉渠相连则只需一口水井灌溉。
输入
给出若干由字母表示的最大不超过50×50具体由(m,n)表示,的农场图
输出
编程求出最小需要打的井数。每个测例的输出占一行。当M=N=-1时结束程序。
输入样例
2 2 DK HF 3 3 ADC FJK IHE -1 -1
输出样例
2 3
提示
参考迷宫问题,实现时关键要解决好各块的表示问题
思路:将每个块转化成左边的形式,如果两个块的上下左右可以接在一起,就将两个块合并。
代码;
#include <iostream>
using namespace std;
struct node
{
char ch;
int visit;
int left,right,up,down;
}maze[100][100];
int n,m;
int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};
bool place(int x,int y,int nx,int ny)
{
if(nx > 0 && nx <= m && ny > 0 && ny <= n && !maze[nx][ny].visit)
{
if(nx == x && ny == y - 1 && maze[x][y].left && maze[nx][ny].right)
return 1;
if(nx == x && ny == y + 1 && maze[x][y].right && maze[nx][ny].left)
return 1;
if(nx == x - 1 && ny == y && maze[x][y].up && maze[nx][ny].down)
return 1;
if(nx == x + 1 && ny == y && maze[x][y].down && maze[nx][ny].up)
return 1;
}
return 0;
}
void dfs(int x,int y)
{
maze[x][y].visit = 1;
for(int i = 0;i < 4;i ++)
{
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(place(x,y,nx,ny))
dfs(nx,ny);
}
}
int main()
{
while(cin >> m >> n && (m != -1 && n != -1))
{
int cnt = 0;
for(int i = 1;i <= m;i ++)
{
for(int j = 1;j <= n;j ++)
{
cin >> maze[i][j].ch;
maze[i][j].visit = 0;
maze[i][j].down = 0;
maze[i][j].up = 0;
maze[i][j].right = 0;
maze[i][j].left = 0;
if(maze[i][j].ch == 'A')
maze[i][j].up = maze[i][j].left = 1;
else if(maze[i][j].ch == 'B')
maze[i][j].up = maze[i][j].right = 1;
else if(maze[i][j].ch == 'C')
maze[i][j].left = maze[i][j].down = 1;
else if(maze[i][j].ch == 'D')
maze[i][j].right = maze[i][j].down = 1;
else if(maze[i][j].ch == 'E')
maze[i][j].down = maze[i][j].up = 1;
else if(maze[i][j].ch == 'F')
maze[i][j].right = maze[i][j].left = 1;
else if(maze[i][j].ch == 'G')
maze[i][j].right = maze[i][j].left = maze[i][j].up = 1;
else if(maze[i][j].ch == 'H')
maze[i][j].up = maze[i][j].down = maze[i][j].left = 1;
else if(maze[i][j].ch == 'I')
maze[i][j].left = maze[i][j].right = maze[i][j].down = 1;
else if(maze[i][j].ch == 'J')
maze[i][j].up = maze[i][j].down = maze[i][j].right = 1;
else if(maze[i][j].ch == 'K')
maze[i][j].up = maze[i][j].down = maze[i][j].right = maze[i][j].left = 1;
}
}
for(int i = 1;i <= m;i ++)
{
for(int j = 1;j <= n;j ++)
{
if(!maze[i][j].visit)
{
dfs(i,j);
cnt ++;
}
}
}
cout << cnt << endl;
}
return 0;
}
/*
2 2
DK
HF
3 3
ADC
FJK
IHE
-1 -1
*/