题目链接: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入门题的时候,只要理清思路,然后敲代码的时候认真一点儿,就没有问题了。