zoj 2165 Red and Black ——BFS入门题

April 7, 2013
zoj BFS

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1165 题意:   给一个字符矩阵,“.”代表黑色格子,“#”代表红色格子,有一个起点“@”,它属于黑色格子,一个人从起点出发,只能走黑色格子,并且只能上下左右走,不能对角线走,问这个人能走到的黑色格子有多少个。输出个数。输入W,H,代表有W列,H行,然后输入一个字符矩阵,输出能走到的最多的黑色格子的个数,包括起点。 思路:   这个题目很简单,和zoj 2110 类似,但是这道题目比那道简单多了,不用剪枝,不用恢复现场,直接深搜就可以。首先找到起点,然后从起点出发,判断这个点是不是被访问过,如果被访问过,就return;否则判断这个格子是不是黑色格子或者是起点,如果是,就cnt++,然后标记这个格子已经被访问过,如果不是,return; 如果没有return,就在这个点的四个方向继续深搜。思路很清晰。1A。


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <stack>
#include <queue>
#include <cmath>
#include <algorithm>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long int LL;
const int MAXN =  0x3f3f3f3f;
const int  MIN =  -0x3f3f3f3f;
const double eps = 1e-9;

int w, h, cnt = 0;
char s[22][22]; bool flag[22][22];
int dir[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
void dfs(int i, int j){
  if (i <= 0 || j <= 0 || i > h || j > w) return;
  if (flag[i][j]) return;
  if (s[i][j] == '.' || s[i][j] == '@'){
    cnt++; flag[i][j] = true;
  } else return;
  for (int k = 0; k < 4; ++k){
    dfs(i + dir[k][0], j + dir[k][1]);
  } 
  return;
}
int main(void){
#ifndef ONLINE_JUDGE
  freopen("zoj2165.in", "r", stdin);
#endif
  while (~scanf("%d%d", &w, &h) && (w+h)){
    getchar(); cnt = 0;
    for (int i = 1; i <= h; ++i){
      for (int j = 1; j <= w; ++j){
        scanf("%c", &s[i][j]);
      } getchar();
    }
    memset(flag, false, sizeof(flag));
    for(int i = 1; i <= h; ++i){
      for (int j = 1; j <= w; ++j){
        if (s[i][j] == '@'){
          dfs(i, j); break;
        }
      }
    }
    printf("%d\n",cnt);
  }

  return 0;
}

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

comments powered by Disqus