搜索算法(二)--DFS/BFS求解炸弹人问题(JAVA )

炸弹人问题

问题描述:小人可以在迷宫中任意地方放置一个炸弹,炸弹可以在以该点为中心的十字方向杀死怪物,但是触碰到墙之后不再能传递攻击。求将一个炸弹放在哪个位置可以杀死更多的怪物??

炸弹人

Input:
输入

13 13
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
3 3

Output:
7 11 10
即(7, 11)坐标处可以杀死10个怪物

思路一:遍历图中的每个点,若非墙壁,怪物则计算该点可以杀死多少怪物,循环遍历,找出最大之(注:但是,不幸的是,这样的的方法对于一些特殊的点不适用,例如图中的(1,11)点)

思路二:BFS/DFS,先筛选出可以抵达的点,再计算

DFS

package Bomberman;

import java.util.Scanner;

public class DFS {
    static char[][] a = new char[20][20];
    static int[][] book = new  int[20][20];
    static Scanner input = new Scanner(System.in);
    static int max = 0;
    static int mx, my;
    static int n, m;
    public static void main(String[] args) {
        n = input.nextInt();
        m = input.nextInt();
        for (int j = 0; j < n; j++) {
            String str = input.next();
            a[j] = str.toCharArray();
        }
        int startX = input.nextInt();
        int startY = input.nextInt();
        book[startX][startY] = 1;
        max = getsum(startX, startY);
        mx = startX;
        my = startY;
        dfs(startX, startY);

        System.out.println(mx + " " + my + " " + max);
    }
    public static void dfs(int x, int y) {
        /**
         * 右、下、左、上
         * */
        int sum, tx, ty;
        int[][] next = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        sum = getsum(x, y);
        if (sum > max) {
            max = sum;
            mx = x;
            my = y;
        }
        for (int i = 0; i < 4; i++) {
            tx = x + next[i][0];
            ty = y + next[i][1];
            if (tx < 0 || tx > n - 1 || ty < 0 || ty > m - 1) {
                continue;
            }
            if (a[tx][ty] == '.' && book[tx][ty] == 0) {
                book[tx][ty] = 1;
                dfs(tx, ty);
            }
        }
        return;
    }
    public static int getsum(int i, int j) {
        int x, y;
        int sum = 0;
        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            x--;
        }
        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            x++;
        }
        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            y--;
        }
        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            y++;
        }
        return sum;
    }
}

BFS

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class note {
    int x;
    int y;
    note(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class BFS {
    static char[][] a = new char[20][20];
    static int[][] book = new int[20][20];
    static Queue<note> queue = new LinkedList<>();
    static Scanner input = new Scanner(System.in);
    static int n, m;
    static int max=0, mx, my;

    public static void main(String[] args) {
        /**
         *  "#"代表墙,"G"代表怪物,"."代表放置炸弹的位置
         * */
        n = input.nextInt();
        m = input.nextInt();
        for (int l = 0; l < n; l++) {
            String str  = input.next();
            a[l] = str.toCharArray();
        }
        int startX = input.nextInt();
        int startY = input.nextInt();

        queue.offer(new note(startX, startY));
        max = getnum(startX, startY);
        mx = startX;
        my = startY;

        bfs();

        System.out.println(mx + " " + my + " " + max);
    }

    public static void bfs() {
        int tx, ty, sum;
        int[][] next = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        while (!queue.isEmpty()) {
            for (int l = 0; l < 4; l++) {
                tx = queue.peek().x + next[l][0];
                ty = queue.peek().y + next[l][1];

                if (tx < 0 || tx > n - 1 || ty < 0 || ty > m - 1) {
                    continue;
                }
                if (a[tx][ty] == '.' && book[tx][ty] == 0) {
                    book[tx][ty] = 1;
                    queue.offer(new note(tx, ty));
                    sum = getnum(tx, ty);
                    if (sum > max) {
                        max = sum;
                        mx = tx;
                        my = ty;
                    }
                }
            }
            queue.remove();
        }
    }
    /**
     * 获取在某点放置炸弹可以杀死的怪物数
     * */
    public static int getnum(int i, int j) {
        int sum, x, y;
        sum = 0;

        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            x--;
        }

        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            x++;
        }

        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            y--;
        }

        x = i;
        y = j;
        while (a[x][y] != '#') {
            if (a[x][y] == 'G') {
                sum++;
            }
            y++;
        }

        return sum;
    }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 八数码问题是一种典型的搜索问题BFS算法可以用于求解。使用BFS算法求解八数码问题的时间复杂度为O(b^d),其中b是分支因子,d是最短路径的深度。在八数码问题中,分支因子为4,最短路径的深度最多为31步。因此,BFS算法的时间复杂度为O(4^31)。这个复杂度非常大,因此在实际操作中,需要采用一些优化策略,如使用启发式搜索算法来减少搜索空间。 ### 回答2: 运用BFS算法求解八数码问题算法时间复杂度为O(b^d),其中b表示每个状态的分支数(即每个数字的可能取值个数),d表示目标状态的深度(即最少需要的步数)。具体解释如下: 八数码问题是一个搜索问题,即在初始状态下,通过不断移动数字,将八个数字按特定顺序排列成目标状态。BFS算法是一种广度优先搜索,它按照逐层扩展的方式搜索可能的解。具体操作是从初始状态开始,首先将初始状态加入一个队列中,然后逐个取出队列中的状态,将它的下一步可能的状态加入队列末尾,并标记为已访问。重复这个过程,直到找到目标状态或队列为空。 在八数码问题中,每个状态可以分为九个位置,每个位置上可以放置一个数字。每一步,将一个数字移动到空格上或者将空格移动到一个数字上,得到一个新的状态。每个位置上的数字有4个可能的移动方向(上下左右),所以每个状态的分支数为4。而目标状态的深度是固定的,为一个常数值。 在BFS算法中,每个状态只会被访问一次,因此时间复杂度取决于需要搜索的状态数。假设初始状态的深度为d,那么需要搜索的状态数为b^0 + b^1 + ... + b^(d-1) + b^d。根据等比数列的求和公式,这个和为(b^(d+1) - 1) / (b - 1)。 因此,运用BFS算法求解八数码问题的时间复杂度为O(b^d)。需要注意的是,在实际应用中,由于状态数可能非常庞大,通常会加入一些剪枝策略来减少实际搜索的状态数,以提高算法效率。 ### 回答3: 八数码问题是一个经典的搜索问题,可以利用BFS算法来解决。BFS算法的时间复杂度取决于问题空间的规模以及搜索的策略。对于八数码问题,我们可以将每个状态看作一个节点,并以初始状态为起点,通过不断扩展并生成后继状态的方式进行搜索,直到找到目标状态或者搜索完整个状态空间。 在八数码问题中,初始状态有 9! 种可能的排列方式,即 9 的阶乘。对于某个状态来说,可以通过交换两个相邻数字来生成下一步的状态,这样每个节点的后继节点个数为 2。因此,状态空间的规模可以表示为 9! * 2 * (2 * 2 * ... * 2),其中 2 出现 9! 次。 在BFS算法中,每个节点都会被访问一次并加入队列中进行扩展,因此总的时间复杂度可以表示为 O(V + E),其中 V 是节点数,E 是边数。在八数码问题中,节点数 V 为状态空间的规模,即 9! * 2 * (2 * 2 * ... * 2),边数 E 可以近似看作节点数的常数倍。 综上所述,对于解八数码问题BFS算法,时间复杂度大致为 O(9! * 2 * (2 * 2 * ... * 2)),其中 2 出现 9! 次。但是值得注意的是,状态空间的规模可能过大,导致实际运行时间非常长。因此,在实际应用中,可能需要借助一些剪枝策略或者启发式搜索来提高效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值