POJ - 1979

题目翻译:
有一个长方形的房间,上面覆盖着方形瓷砖。每块瓷砖的颜色为红色或黑色。一个男人站在一块黑色的瓷砖上。从一个图块中,他可以移动到四个相邻的图块之一。但是他不能在红色瓷砖上移动,他只能在黑色瓷砖上移动。

编写一个程序来计算他可以通过重复上述动作来达到的黑色瓷砖的数量。

输入

输入由多个数据集组成。数据集从包含两个正整数 W 和 H 的行开始;W 和 H 分别是 x 和 y 方向上的瓦片数。W 和 H 不超过 20。

数据集中还有 H 多行,每行都包含 W 个字符。每个字符代表瓷砖的颜色,如下所示。

'.' - 黑色瓷砖
'#' - 红色瓷砖
'@' - 黑色瓷砖上的男人(在数据集中恰好出现一次)
输入的结尾由一条由两个零组成的线表示。

输出

对于每个数据集,您的程序应输出一行,其中包含他从初始瓦片(包括自身)可以到达的瓦片数量。

样本

输入复制输出复制
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0

这道题有两个很坑人的点的 ,一个是我们看一下输入n,m,(我以为那是n行m列,然后一直在算,最后的最后,我裂开了,原来是m行n列);另一个就是,这道题不能用回溯,就是和dfs()的板子有两句不相同,其他的都一样;这两个错误我调了一上午,至于他为啥不能回溯,我感觉就是走一遍之后,不能再走第二遍了;

题很简单,思路就是先找到那个'@',然后记录他的下标,之后dfs(),在dfs()中注意我说的第二个点,之后,只要你熟悉dfs()的模板,你就知道怎么写了,我这里只提供思路和参考答案,具体的dfs(),还得靠各位自己找了(废话真多,对吧,O(∩_∩)O哈哈~),上代码

#include<iostream>
#include<cstring>
using namespace std;
char array[30][30];
int vis[30][30];
int n,m,cnt;
int ans[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void dfs(int x,int y)
{
	vis[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int dx=x+ans[i][0];
		int dy=y+ans[i][1];
		if(dx>=0&&dx<=m-1&&dy>=0&&dy<=n-1&&array[dx][dy]=='.'&&vis[dx][dy]==0)
		{	 
//			vis[dx][dy]=1;
			cnt++;
			dfs(dx,dy);
//			vis[dx][dy]=0;
		}
	}
}
int main()
{
	while(1)
	{
		int sx,sy;
		cin>>n>>m;	//n是列,m是行 
		if(n==0&&m==0)
			break;
		memset(vis,0,sizeof vis);
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<n;j++)
			{
				cin>>array[i][j];
				if (array[i][j]== '@') 
				{
					sx=i;
					sy=j;
                }
			}	
		}
		cnt=1;
		dfs(sx,sy);
		vis[sx][sy]=1;
		cout<<cnt<<"\n";
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值