题目链接:
题意:
其实就是有一个地图,问能走动的范围有多少?。其中.'@'为起点, ' . '为路,可以到达。' # '为墙,不能通过。
输入:
多组数据,每组数据的第一行输入两个数w和h,w表示列数,h表示行数,然后下面的h行就是输入地图。输入结束为当w和h同时为0。
输出:
每组数据输出一个数,表示可以走动的范围,包括起点。
分析:
其实就是用一个递归,也就是DFS,主要先找到起点的位置,然后从位置出发。
需要一个递归函数,还有几个数组。
- 一个字符地图数组map[i][j]表示i行j列的字符。
- 一个二维的标志数组vis[][],用于标记是否走过
- 递归函数的终止条件:超过地图边界,遇到不能走,或者遇到走过的。
- 还有一个要表示走上下左右四个方向,可以用两个一位数组dx[],dy[],结合,四个方向就是for循环四种情况
还有一个陷阱,关于二维的字符数组输入的问题,具体可以查看我的另一篇博客:关于单个字符(%c)用scanf输入的错误
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char str[30][30];
int vis[30][30];
int w,h;
int sx,sy;
int ans;
int dx[4] = {-1,1,0,0};
int dy[4] = {0,0,1,-1};
void dfs(int x,int y)
{
// 边界条件,过边缘,是#,或者访问过
if(x<0 || x>=h || y<0 || y>=w || str[x][y]=='#' || vis[x][y])
return;
vis[x][y] = 1; // 这次就走这里了,走了说明可以++
ans++;
for(int i = 0;i < 4;i++) // 然后几个方向都走走
{
dfs(x+dx[i],y+dy[i]);
}
}
int main()
{
//freopen("POJ1979.txt","r",stdin);
while(1)
{
memset(vis,0,sizeof(vis));
scanf("%d %d",&w,&h);
if(w==0 && h==0)
break;
for(int i = 0;i < h;i++)
{
for(int j = 0;j < w;j++)
{
scanf(" %c",&str[i][j]);
if(str[i][j] == '@')
{
sx = i;
sy = j;
}
}
}
ans = 0; // 能就++
dfs(sx,sy); // 从这个起点开始
cout << ans << endl;
}
return 0;
}