zoj2412:Farm Irrigation

13 篇文章 0 订阅

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  ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值