DFS简单题 杭电1241 POJ 1154

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;
}
发布了56 篇原创文章 · 获赞 49 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/IBelieve2016/article/details/74009172
今日推荐