DFS简单题 杭电1241 POJ 1154

来源:互联网 发布:java中的数组声明 编辑:程序博客网 时间:2024/06/11 08:14

DFS和BFS两种搜索方式,DFS是利用递归方式,需要一个visited数组,记录是否将节点访问过。BFS用队列来存储部分中间节点。
数据量小,而且要求简单,就用DFS。

杭电1241

DFS简单题
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1241
题目大意是:一个公司开采石油,在一个矩形区域,每个元素要么有油,要么没油,如果有油的地方是连接的(八个方向),就算是一片油区,问总共有多少油区。

思路:对每个元素按顺序搜索,如果该元素有油而且没搜索过,那么使用DFS来搜索周围其他地方,并标志上visited表示已经搜索过。使用DFS搜索完这个元素之后,表明这片油区的所有元素已经访问过,所以ans++,继续往下搜索。

代码如下:
写程序时遇到一个问题,用VS2013,scanf那里竟然读取不了元素,就是我在cin前边注释掉的那行,原因是scanf在读char类型时把空格和回车都算上了,而读int这样的类型的时候,会自动匹配一下,所以以后要么用cin读字符,要么就在有空格或者回车的地方读一个空的变量。

#include <algorithm>#include <iostream>#include <cstring>#include <string>#include "stdio.h"using namespace std;char a[100][100]; //输入信息int visited[100][100]; //记录每个点是否被访问,1表示已经访问过int direction[8][2] = { 1, 1, 1, 0, 1, -1, 0, -1, 0, 1, -1, -1, -1, 1, -1, 0 };int m, n;int ans = 0; //表示最终结果,即连通区域的个数void dfs(int nx, int ny){    for (int i = 0; i < 8; i++){        int x = nx + direction[i][0];        int y = ny + direction[i][1];        if (x >= 0 && x < m && y >= 0 && y < n && visited[x][y] != 1 && a[x][y]=='@'){            visited[x][y] = 1;            dfs(x, y);        }    }}int main(){    while (true){        ans = 0;        scanf("%d %d", &m, &n);        if (m == 0 && n == 0) break;        for (int i = 0; i < m; i++){            for (int j = 0; j < n; j++){                //scanf("%c", &a[i][j]);                cin >> a[i][j];            }        }        memset(visited, 0, sizeof(visited));        for (int i = 0; i < m; i++){            for (int j = 0; j < n; j++){                if (visited[i][j] != 1 && a[i][j] == '@'){                    visited[i][j] = 1;                    dfs(i, j);                    ans++;                }            }        }        printf("%d\n", ans);    }    return 0;}

POJ 1154

题目链接:
大意:有一个矩阵,元素是26个大写字母,从第一行第一列开始出发,每次可以往前后左右走一格,但是比如之前走过了字母’A’,以后就不能走这个字母了。问最多可以走几步。

思路:

大概意思和上面写的杭电1241差不多,只是不需要visited数组,变成了v[26]数组,然后就是简单的DFS。

#include <algorithm>#include <cstring>#include <iostream>#include "stdio.h"using namespace std;char a[21][21];int v[26];int m, n;int direction[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };int ans, temp;void dfs(int x, int y){    for (int i = 0; i < 4; i++){        int nx = x + direction[i][0];        int ny = y + direction[i][1];        if (nx >= 0 && nx < m && ny >= 0 && ny < n && v[a[nx][ny] - 'A'] != 1){            v[a[nx][ny]-'A'] = 1;            temp++;            dfs(nx, ny);            if (ans < temp) ans = temp; //每次记录下最大值来            temp--; //别忘了还要自减,恢复原来的状态            v[a[nx][ny]-'A'] = 0;         }    }}int main(){    cin >> m >> n;    for (int i = 0; i < m; i++){        for (int j = 0; j < n; j++){            cin >> a[i][j];        }    }    ans = 1;    temp = 1;    memset(v, 0, sizeof(v));    v[a[0][0] - 'A'] = 1; //千万不要忘了开始要将出发点设置为1    dfs(0, 0);    cout << ans << endl;    return 0;}
原创粉丝点击