HDU1312 Red and Black(BFS)(step与sum)

ACM 专栏收录该内容
211 篇文章 0 订阅

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. 

Write a program to count the number of black tiles which he can reach by repeating the moves described above. 
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20. 

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows. 

'.' - a black tile 
'#' - a red tile 
'@' - a man on a black tile(appears exactly once in a data set) 
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself). 
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13



题意:给出一个m行n列的迷宫(注意不是n行m列),'.'表示能走的格子,'#'表示墙,从起点'@'开始,问你在这个迷宫中最多能走多少个格子。


解题思路:好多天没有做题手好生啊…看什么题都没有思路所以这才掘个坟把以前刚学习bfs的第一道题重新拿出来做一下…

bfs的搜索方式可以类比病毒在机体内的感染过程=。=

从母体开始不断的向四周感染,直到这个机体内的所有细胞都已经被感染完毕。

那么在“不断地向四周感染”的过程中,我们又可以放大来看,感染一周的细胞需要个顺序,也就是先感染上面的细胞然后是右、下、左。这一轮感染完毕。

下一轮感染最开始的细胞也就是上一轮最开始被感染的那个细胞,也就是上一轮中的“上面的细胞”。


Mark以做提醒:

结构体中的step是伴随每个状态记录从起点到当前点的距离。

而本题中要求的并不是最短距离而是能够到达的所有格子的个数,所以我们需要另外设置一个计数变量sum,当每能走出一步时,sum即进行累加。

也就是说这道题我们的bfs并不是解决最短路径的问题,而是借助bfs的方式来统计这个图中所有符合条件的格子。


如果以上能够理解,那么本题为什么用bfs而不是dfs呢?0.0


AC代码:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

char mp[25][25];
int n,m,book[25][25];
int nx[4][2]={0,1,-1,0,0,-1,1,-0};

struct node
{
	int x,y;
};

node getnode(int x,int y)
{
	node q;
	q.x=x;
	q.y=y;
	return q;
}

int bfs(int x,int y)
{
	int sum=1;
	queue<node> q;
	q.push(getnode(x,y));
	while(!q.empty())
	{
		for(int i=0;i<4;i++)
		{
			int tx=q.front().x+nx[i][0];//优先队列为q.top()
			int ty=q.front().y+nx[i][1];
			if(tx>=0&&tx<n&&ty>=0&&ty<m&&book[tx][ty]==0&&mp[tx][ty]=='.')
			{
				book[tx][ty]=1;
				sum++;
				q.push(getnode(tx,ty));
			}
		}
		q.pop();
	}
	return sum;
}

int main()
{
	while(~scanf("%d%d",&m,&n)&&n+m)
	{
		memset(book,0,sizeof(book));
		for(int i=0;i<n;i++)
			scanf("%s",mp[i]);
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(mp[i][j]=='@')
				{
					book[i][j]=1;
					printf("%d\n",bfs(i,j));
				}
			}
		}
	}
	return 0;
}

针对循环优化一下:一找到起点即结束循环。

int flag=0;
for(int i=0;i<n;i++)
{
	for(int j=0;j<m;j++)
	{
		if(mp[i][j]=='@')
		{
			book[i][j]=1;
			printf("%d\n",bfs(i,j));
			flag=1;
			break;
		}
	}
	if(flag) break;
}

优化后的运行时间是0ms0.0

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值