题目
Problem Description
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).
题目大致解释
代码1
#include <bits/stdc++.h>
using namespace std;
char room[30][30];
int sum=0;
int n,m;
int change[4][2] = {
{
-1,0},{
0,-1},{
1,0},{
0,1}};
void DFS (int X,int Y)
{
int x1,y1;
room[X][Y]='#';
sum++;
for (int i=0;i<4;i++)
{
x1=X+change[i][0];
y1=Y+change[i][1];
if (room[x1][y1]=='.'&&x1<n&&x1>=0&&y1<m&&y1>=0)
DFS(x1,y1);
}
}
int main()
{
int x,y;
while(cin>>n>>m)
{
if (n==0&&m==0) break;
for (int j=0; j<m; j++)
{
for (int i=0; i<n; i++)
{
cin>>room[i][j];
if (room[i][j]=='@')
{
x=i;
y=j;
}
}
}
DFS(x,y);
cout<<sum<<endl;
sum=0;
}
return 0;
}
理解1
运用了DFS的思想进行递归。
定义一个room用来存放砖块的分布,change用来进行上下左右的移动(通过加减坐标的大小)。
在DFS函数中,从起点‘@’开始寻找,for循环进行移动坐标的位置,若移动后的坐标显示为’.’,则该座标进入DFS函数,再以它为起点寻找’.’。走过的砖块记录为’#’,标记为无法再次通过。
__DFS解析:
代码2
//ECUST luoyongjun
#include<bits/stdc++.h>
using namespace std;
char room[23][23];
int dir[4][2] = {
{
-1,0}, //向左。左上角坐标是(0, 0)
{
0,-1}, //向上
{
1,0}, //向右
{
0,1} //向下
};
int Wx, Hy, num; //Wx行,Hy列。用num统计可走的位置有多少
#define CHECK(x, y) (x<Wx && x>=0 && y >=0 && y<Hy) //是否在room里
struct node {
int x,y;};
void BFS(int dx,int dy){
num=1; //起点也包含在砖块内
queue <node> q; //队列中放坐标点
node start, next;
start.x = dx;
start.y = dy;
q.push(start);
while(!q.empty()) {
start = q.front();
q.pop();
//cout<<"out"<<start.x<<start.y<<endl; //打印出队列情况,进行验证
for(int i=0; i<4; i++) {
//按左、上、右、下,4个方向顺时针逐一搜索
next.x = start.x + dir[i][0];
next.y = start.y + dir[i][1];
if(CHECK(next.x,next.y) && room[next.x][next.y]=='.') {
room[next.x][next.y]='#'; //进队之后,标记为已经处理过
num++;
q.push(next);
}
}
}
}
int main(){
int x, y, dx, dy;
while (cin >> Wx >> Hy) {
//Wx行,Hy列
if (Wx==0 && Hy==0) //结束
break;
for (y = 0; y < Hy; y++) {
//有Hy列
for (x = 0; x < Wx; x++) {
//一次读入一行
cin >> room[x][y];
if(room[x][y] == '@') {
//读入起点
dx = x;
dy = y;
}
}
}
num = 0;
BFS(dx, dy);
cout << num << endl;
}
return 0;
}
理解2
这个代码是ppt上的标准代码,运用了BFS的方法。
__BFS解析:
先做题,之后再理解