zoj 2165 Red and Black ——BFS入门题

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1165

题意:

  给一个字符矩阵,“.”代表黑色格子,“#”代表红色格子,有一个起点“@”,它属于黑色格子,一个人从起点出发,只能走黑色格子,并且只能上下左右走,不能对角线走,问这个人能走到的黑色格子有多少个。输出个数。输入W,H,代表有W列,H行,然后输入一个字符矩阵,输出能走到的最多的黑色格子的个数,包括起点。

思路:

  这个题目很简单,和zoj 2110 类似,但是这道题目比那道简单多了,不用剪枝,不用恢复现场,直接深搜就可以。首先找到起点,然后从起点出发,判断这个点是不是被访问过,如果被访问过,就return;否则判断这个格子是不是黑色格子或者是起点,如果是,就cnt++,然后标记这个格子已经被访问过,如果不是,return; 如果没有return,就在这个点的四个方向继续深搜。思路很清晰。1A。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cctype>
 6 #include <stack>
 7 #include <queue>
 8 #include <cmath>
 9 #include <algorithm>
10 #define lson l, m, rt<<1
11 #define rson m+1, r, rt<<1|1
12 using namespace std;
13 typedef long long int LL;
14 const int MAXN =  0x3f3f3f3f;
15 const int  MIN =  -0x3f3f3f3f;
16 const double eps = 1e-9;
17 
18 int w, h, cnt = 0;
19 char s[22][22]; bool flag[22][22];
20 int dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
21 void dfs(int i, int j){
22   if (i <= 0 || j <= 0 || i > h || j > w) return;
23   if (flag[i][j]) return;
24   if (s[i][j] == '.' || s[i][j] == '@'){
25     cnt++; flag[i][j] = true;
26   } else return;
27   for (int k = 0; k < 4; ++k){
28     dfs(i + dir[k][0], j + dir[k][1]);
29   } 
30   return;
31 }
32 int main(void){
33 #ifndef ONLINE_JUDGE
34   freopen("zoj2165.in", "r", stdin);
35 #endif
36   while (~scanf("%d%d", &w, &h) && (w+h)){
37     getchar(); cnt = 0;
38     for (int i = 1; i <= h; ++i){
39       for (int j = 1; j <= w; ++j){
40         scanf("%c", &s[i][j]);
41       } getchar();
42     }
43     memset(flag, false, sizeof(flag));
44     for(int i = 1; i <= h; ++i){
45       for (int j = 1; j <= w; ++j){
46         if (s[i][j] == '@'){
47           dfs(i, j); break;
48         }
49       }
50     }
51     printf("%d\n",cnt);
52   }
53 
54   return 0;
55 }

感觉做这种DFS入门题的时候,只要理清思路,然后敲代码的时候认真一点儿,就没有问题了。

原文地址:https://www.cnblogs.com/liuxueyang/p/3005851.html