ACM BFS,DFS入门题(附代码解释)

目录

HDU 1312 Red and Black(BFS)

HDU1372 Knight Moves(BFS) 

HDU2717 Catch That Cow(BFS)

HDU 1241 Oil Deposits(DFS) 

HDU - 1181 变形课(DFS)


HDU 1312 Red and Black(BFS)

题意:从‘@’点出发,问能到达的最多的点有多少,‘#’不可经过,计算结果包括‘@’。

题解:直接从起点广搜即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;
struct node {
    int x, y;
};
bool vis[21][21];
int fx[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
char str[21][21];
int m, n;

int check(int x, int y) {
    if (x < 0 || y < 0 || x >= n || y >= m || vis[x][y] || str[x][y] == '#')
        return 0;
    return 1;
}

int bfs(int x, int y) {
    int sum = 1;
    node now, next;
    now.x = x,now.y = y;
    queue<node> q;
    q.push(now);
    vis[now.x][now.y] = 1;
    while (!q.empty()) {
        now = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            next.x = now.x + fx[i][0];
            next.y = now.y + fx[i][1];
            if (check(next.x, next.y)) {
                vis[next.x][next.y] = 1;
                sum++;
                q.push(next);
            }
        }
    }
    return sum;
}

int main() {
    while (scanf("%d%d", &m, &n) && m + n) {
        int x, y;
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < n; i++){
            scanf("%s", str[i]);
            for (int j = 0; j < m; j++) {
                if (str[i][j] == '@') {
                    x = i,y = j;
                    break;
                }
            }
        }
        printf("%d\n",bfs(x, y));
    }
    return 0;
}

 

HDU1372 Knight Moves(BFS) 

题意:给出马的起点和终点,让你求出从起点走多少步能到终点。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;
int fx[8][2] = {1, 2, 2, 1, 2, -1, 1, -2, -1, -2, -2, -1, -1, 2, -2, 1};
bool vis[10][10];
char st[5], ed[5];
int x2, y2;
struct node {
    int x, y, t;
};

int check(int x, int y) {
    if (x < 0 || y <= 0 || x >= 8 || y > 8 || vis[x][y])
        return 0;
    return 1;
}

int bfs(int x, int y) {
    queue<node> q;
    node now, next;
    now.x = x, now.y = y, now.t = 0;
    vis[now.x][now.y] = 1;
    q.push(now);
    while (!q.empty()) {
        now = q.front();
        q.pop();
        if (now.x == x2 && now.y == y2)
            return now.t;
        for (int i = 0; i < 8; i++) {
            next.x = now.x + fx[i][0];
            next.y = now.y + fx[i][1];
            if (check(next.x, next.y)) {
                next.t = now.t + 1;
                vis[next.x][next.y] = 1;
                q.push(next);
            }
        }
    }
}

int main() {
    while (scanf("%s%s", st, ed) != EOF) {
        memset(vis, 0, sizeof(vis));
        int x1 = st[0] - 'a', y1 = st[1] - '0';
        x2 = ed[0] - 'a', y2 = ed[1] - '0';
        int sum = bfs(x1, y1);
        printf("To get from %s to %s takes %d knight moves.\n", st, ed, sum);
    }
    return 0;
}

 

HDU2717 Catch That Cow(BFS)

题意:约翰和牛在一条轴上,牛不动,约翰抓牛:约翰可以从x点x-1 x + 1,花费一分钟,也可以传送:约翰可以从x传送到点2×X,花费一分钟。问约翰最少花多少时间可以抓到牛。

 

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;
bool maps[200001];
int x, y;
struct node {
    int x, t;
};

int bfs() {
    queue<node> q;
    node now, next;
    now.x = x, now.t = 0;
    maps[now.x] = 1;
    q.push(now);
    while (!q.empty()) {
        now = q.front();
        q.pop();
        if (now.x == y)
            return now.t;
        next.x = now.x - 1;
        if (now.x >= 1 && !maps[next.x]) {
            next.t = now.t + 1;
            maps[next.x] = 1;
            q.push(next);
        }
        next.x = now.x + 1;
        if (now.x <= y && !maps[next.x]) {
            next.t = now.t + 1;
            maps[next.x] = 1;
            q.push(next);
        }
        next.x = now.x * 2;
        if (now.x <= y && !maps[next.x]) {
            next.t = now.t + 1;
            maps[next.x] = 1;
            q.push(next);
        }
    }
}

int main() {
    while (scanf("%d%d", &x, &y) != EOF) {
        memset(maps, 0, sizeof(maps));
        if (x >= y)///如果牛在左边直接每次走一步去抓牛
            printf("%d\n", x - y);
        else
            printf("%d\n", bfs());
    }
    return 0;
}

 

HDU 1241 Oil Deposits(DFS) 

题意:给你一片地,要找出里面有多少油田,油田表示为@  要求是只要一个@的八面有@  这就算一个油田。

解析:可通过广搜,然后将连接的油田全部转化成地,看能分别转化几次,就有几块油田。

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
char str[101][101];
int fx[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, -1, 1, 1, -1, -1, -1, 1};
int n, m;

int check(int x, int y) {
    if (x >= 0 && x < m && y >= 0 && y < n && str[x][y] == '@')
        return 1;
    return 0;
}

void dfs(int x, int y) {
    int x1, y1;
    for (int i = 0; i < 8; i++) {
        x1 = x + fx[i][0];
        y1 = y + fx[i][1];
        if (check(x1, y1)) {
            str[x1][y1] = '*';
            dfs(x1, y1);
        }
    }
}

int main() {
    while (scanf("%d%d", &m, &n) && m) {
        int sum = 0;
        for (int i = 0; i < m; i++)
            scanf("%s", str[i]);
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (str[i][j] == '@') {
                    dfs(i, j);
                    sum++;
                }
        printf("%d\n", sum);
    }
    return 0;
}

 

HDU - 1181 变形课(DFS)

PS:简单的DFS,只是注意输入单词要是首尾字母不能够一样,其次不能做首尾单词相同的转化。

#include<stdio.h>
#include<cstring>

using namespace std;
char str2[10000][5];
int a[10000], flag, t;

void dfs(int s) {
    for (int i = 0; i < t; i++) {
        if (str2[i][0] == str2[s][1] && str2[i][1] == 'm') {
            flag = 1;
            return;
        }
        if (!a[i] && str2[i][0] == str2[s][1]) {
            a[i] = 1;
            dfs(i);
        }
    }
}

int main() {
    char temp[1000];
    while (scanf("%s", temp) != EOF) {
        int s = 0, l = strlen(temp);
        if (temp[0] != temp[l - 1]) {
            str2[s][0] = temp[0];
            str2[s][1] = temp[l - 1];
            s++;
        }
        while (scanf("%s", temp) && temp[0] != '0') {
            int l = strlen(temp);
            if (temp[0] != temp[l - 1]) {
                str2[s][0] = temp[0];
                str2[s][1] = temp[l - 1];
                s++;
            }
        }
        t = s,flag = 0;
        memset(a, 0, sizeof(a));
        for (int i = 0; i < s; i++) {
            if (str2[i][0] == 'b')
                a[i] = 1;
            dfs(i);
        }
        if (flag)
            printf("Yes.\n");
        else
            printf("No.\n");
    }
    return 0;
}
 

 

©️2020 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值