http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2412
题目大意:有A~K种类型的田地,每种类型的田地都有一中水管类型,现在有一块农田,这块农田有以上类型的水田组成,求至少需要多少个水源。
题目很简单,刚开始看到时候想将每种类型的田地,能与其组合在一块的田地,逐一枚举出来,但是编程的时候发现数据量太大了,然后就写不下去了,然后就上网搜了一下,看了一下别人是怎么存储的,突然发现每块类型田地的高效存储方式,每块田地有上下左右四个方向,而对应的水管也只有这四种方向,如果某个方向有通路就置为1 , 否则置为0 ,这样就简便的多了。
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std ;
const int maxn = 55 ;
struct Node
{
int up ;//上
int dn ;//下
int le ;//左
int rg ;//右
};//用于存放田的类型
int map[maxn][maxn] ;//存放图
int m ;
int n ;
int cont ;//计数
//根据每种田地的类型,如果某个方向有水道则置为1,否则为0 ,例如A{1 ,0 , 1 ,0}
Node dir[11] ={{1 , 0 , 1 , 0} ,{ 1 , 0 , 0 , 1} , {0 , 1 , 1 , 0} , {0 , 1 , 0 , 1},
{1 , 1 , 0 , 0} ,{ 0 , 0 , 1 , 1 } ,{1 , 0 , 1 , 1} ,{1 , 1 , 1 , 0},{0 , 1 , 1 , 1},
{1 , 1 , 0 , 1} ,{1 , 1 , 1, 1}} ;
void dfs(int x , int y) ;
bool input() ;
void work() ;
int main()
{
work() ;
return 0 ;
}
void work()
{
while(input())
{
cont = 0 ;
for(int i = 0 ; i < m ; i ++)
{
for(int j = 0 ; j < n ; j ++)
{
if(map[i][j] >=0 )
{
dfs(i , j) ;
cont ++ ;
}
}
}
printf("%d\n" , cont) ;
}
}
bool input()
{
memset(map , -1 , sizeof(map)) ;//这里将图初始化为-1 ,访问过也会置为-1
char c ;
scanf("%d %d" , &m , &n) ;
if(m < 0 || n < 0 )
return false ;
getchar() ;
int i ;
int j ;
for(i = 0 ; i < m ; i ++ )
{
for(j = 0 ; j < n ; j ++)
{
c = getchar() ;
map[i][j] = c - 'A';
}
getchar() ;
}
return true ;
}
void dfs(int x , int y)
{
//边界条件
if(y < 0 && (x==m || x < 0))
return ;
if(y==n && ( x==m || x < 0))
return ;
//作为地图上每个块的类型
int p = map[x][y] ;
int q ;
map[x][y] = -1 ;
//如果上通,则考虑该地的上一块的类型,它的下方是不是通的,还有不能越界
if(dir[p].up == 1 && x > 0)
{
q = map[x-1][y] ;
if(q !=-1 && dir[q].dn )
{
dfs(x-1 , y) ;
}
}
//如果左通,则考虑该地的左侧一块的类型,它的右方是不是通的,不能越界
if(dir[p].le == 1 && y > 0)
{
q = map[x][y-1] ;
if(q != -1 && dir[q].rg)
{
dfs( x , y-1) ;
}
}
//如果右通,则考虑该地的右侧一块的类型,它的左方是不是通的,不能越界
if(dir[p].rg == 1 && y < n - 1 )
{
q = map[x][y+1] ;
if(q != -1 && dir[q].le)
{
dfs(x , y+1) ;
}
}
//如果下通,则考虑该地的下方一块的类型,它的上方是不是通的,不能越界
if(dir[p].dn == 1 && x < m -1)
{
q = map[x+1][y] ;
if(q != -1 && dir[q].up)
{
dfs(x+1 , y) ;
}
}
return ;
}