首页 > 试题广场 >

迷宫游戏

[编程题]迷宫游戏
  • 热度指数:1698 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
薯队长最近在玩一个迷宫探索类游戏,迷宫是一个N*N的矩阵形状,其中会有一些障碍物禁止通过。这个迷宫还有一个特殊的设计,它的左右 边界以及上下边界是连通的,比如在(2,n)的位置继续往右走一格可以到(2,1),    在(1,2)的位置继续往上走一格可以到(n,2)。请问薯队长从起点位置S,最少走多少格才能到达迷宫的出口位置E。 

输入描述:
第一行正整数N,接下来N行字符串
’.’表示可以通过
’#’表示障碍物
’S’表示起点(有且仅有一个)
’E’表示出口(有且仅有一个)
对于50%的数据N<10
对于100%的数据N<10^3 


输出描述:
输出一个整数。表示从S到E最短路径的长度,    无法到达则输出    -1 
示例1

输入

5
.#...
..#S.
.E### 
..... 
.....

输出

4
n = int(input())
grid, S_OR = [], []
for i in range(n):
    crow = list(input())
    if 'S' in crow:
        S_OR = [i, crow.index('S')]
    grid.append(crow)


def BFS(grid, S_OR, n):
    dx, dy = [1, -1, 0, 0], [0, 0, 1, -1]
    queue = [S_OR]
    visited = [[False for _ in range(n)] for _ in range(n)]
    visited[S_OR[0]][S_OR[1]] = True
    step = 0
    while queue:
        step += 1
        len_queue = len(queue)
        for _ in range(len_queue):
            q = queue.pop(0)
            for _x, _y in zip(dx, dy):
                x, y = (q[0] + _x + n) % n, (q[1] + _y + n) % n
                if not visited[x][y] and grid[x][y] != '#':
                    if grid[x][y] == 'E':
                        return step
                    queue.append([x, y])
                    visited[x][y] = True
    return -1


print(BFS(grid, S_OR, n))

发表于 2020-08-29 20:16:41 回复(0)
这一题的测试用例不完整,,,下面是我的思路,大佬可以点评一下
使用两个二维数组,将起点步数设为0。广度遍历的思想。用队列记录点,当一个新点出队时,检查上下左右四个点(注意连通性条件)。如果这些点是墙,我们就不处理。否则,若点未访问过或者之前的步数太多(走的太麻烦),跟新步数并把这一点入队。(我的疑问就是这里,走的太麻烦的点还要入队吗?自我感觉,广度遍历不需要,因为广度不会出现这种情况,但是深度遍历是需要的)
n = int(input())
mat = [[0] * n] * n
result = [[-1] * n for _ in range(n)]
for i in range(n):
    mat[i] = list(input())
queue = []

for i in range(n):
    for j in range(n):
        if mat[i][j] == 'S':
            queue.append([i, j])
            result[i][j] = 0
        if mat[i][j] == 'E':
            end = [i, j]
while queue:
    point = queue.pop(0)
    x = point[0]
    y = point[1]
    left = [x, n - 1] if y == 0 else [x, y - 1]
    right = [x, 0] if y == n - 1 else [x, y + 1]
    up = [n-1, y] if x == 0 else [x - 1, y]
    down = [0, y] if x == n - 1 else [x + 1, y]
    near_p = [left, right, up, down]
    for point in near_p:
        if mat[point[0]][point[1]] != '#':
            if result[point[0]][point[1]] == -1&nbs***bsp;result[point[0]][point[1]] > result[x][y] + 1:
                queue.append(point)
                result[point[0]][point[1]] = result[x][y] + 1
print(result[end[0]][end[1]])


编辑于 2020-06-11 15:19:29 回复(0)
bfs算法,在node结构体中添加步数数据,每次入队的节点步数为对头步数+1,边界穿越单独考虑,判断穿越后的位置能不能走。
#include<iostream>
#include<vector>
#include<string>
#include<queue>
using namespace std;
//节点表示可以走的位置横坐标纵坐标及从起到到这的步数
struct node{
    int x;
    int y;
    int path;//步数
    node(int a,int b,int c){
        x=a;y=b;path=c;
    }
};
int bfs(vector<vector<char>>&arr,int i,int j,int m,int n){
    queue<node*> q;
    q.push(new node(i,j,0));//起点步数设为0
    arr[i][j]='#';//走过的点设为障碍防止往回走
    //判断队列头的节点上下左右四个节点是否能走,能走再看是不是终点
    //不是终点就入队,步数设为对头的步数+1,因为这个位置是从队头走一步过来的
    while(!q.empty()){
        node* cur=q.front();
        q.pop();
        if(cur->x-1>=0&&arr[cur->x-1][cur->y]!='#'){
            if(arr[cur->x-1][cur->y]=='E')
                return cur->path+1;
            q.push(new node(cur->x-1,cur->y,cur->path+1));
            arr[cur->x-1][cur->y]='#';
        }
        //判断是否从边界穿越,如果穿越则判断穿越后的点是否能走
        if(cur->x-1==-1&&arr[arr.size()-1][cur->y]!='#'){
            if(arr[arr.size()-1][cur->y]=='E')
                return cur->path+1;//是终点直接返回
            q.push(new node(arr.size()-1,cur->y,cur->path+1));//否则入队
            arr[arr.size()-1][cur->y]='#';
        }
        if(cur->x+1<arr.size()&&arr[cur->x+1][cur->y]!='#'){
            if(arr[cur->x+1][cur->y]=='E')
                return cur->path+1;
            q.push(new node(cur->x+1,cur->y,cur->path+1));
            arr[cur->x+1][cur->y]='#';
        }
        if(cur->x+1==arr.size()&&arr[0][cur->y]!='#'){
            if(arr[0][cur->y]=='E')
                return cur->path+1;
            q.push(new node(0,cur->y,cur->path+1));
            arr[0][cur->y]='#';
        }
        if(cur->y-1>=0&&arr[cur->x][cur->y-1]!='#'){
            if(arr[cur->x][cur->y-1]=='E')
                return cur->path+1;
            q.push(new node(cur->x,cur->y-1,cur->path+1));
            arr[cur->x][cur->y-1]='#';
        }
        if(cur->y-1==-1&&arr[cur->x][arr[0].size()-1]!='#'){
            if(arr[cur->x][arr[0].size()-1]=='E')
                return cur->path+1;
            q.push(new node(cur->x,arr[0].size()-1,cur->path+1));
            arr[cur->x][arr[0].size()-1]='#';
        }
        if(cur->y+1<arr[0].size()&&arr[cur->x][cur->y+1]!='#'){
            if(arr[cur->x][cur->y+1]=='E')
                return cur->path+1;
            q.push(new node(cur->x,cur->y+1,cur->path+1));
            arr[cur->x][cur->y+1]='#';
        }
        if(cur->y+1==arr[0].size()&&arr[cur->x][0]!='#'){
            if(arr[cur->x][0]=='E')
                return cur->path+1;
            q.push(new node(cur->x,0,cur->path+1));
            arr[cur->x][0]='#';
        }
    }
    //如果把能走的点走完队列为空了,没有找到终点则返回-1
    return -1;
}
int main(){
    int N;
    cin>>N;
    vector<int> start(2);
    vector<int> end(2);
    vector<vector<char>> arr(N,vector<char>(N));
    for(int i=0;i<N;i++){
        string line;
        cin>>line;
        for(int j=0;j<N;j++){
            arr[i][j]=line[j];
            if(line[j]=='S'){
                start[0]=i;
                start[1]=j;
            }
            if(line[j]='E'){
                end[0]=i;
                end[1]=j;
            }
        }
    }
    cout<<bfs(arr,start[0],start[1],end[0],end[1]);
}


发表于 2021-09-22 10:36:54 回复(0)
https://blog.csdn.net/weixin_43180675/article/details/106734077,移步我的博客查看,使用bfs算法解题
发表于 2020-06-16 20:02:43 回复(0)
亲测可过 不过牛客网的输入有点烦 代码将就看一下吧
function node(x, y, layer) {
      this.x = x;
      this.y = y;
      this.layer = layer;
    }
    function fn(a, arr) {
      var xStart = -1, yStart = -1;
      var xEnd = -1, yEnd = -1;
      var count = 0;
      for (var i = 0; i < arr.length; i++) {
        for (var k = 0; k < arr[0].length; k++) {
          if (arr[i][k] == 's') {
            xStart = i;
            yStart = k;
          }
          if (arr[i][k] == 'e') {
            xEnd = i;
            yEnd = k;
          }
        }
      }
      var stack = [];
      stack.push(new node(xStart,yStart,0));
      var newArr = arr.slice();
      var x = -1 , y = -1;
      //---------------------------------------bfs
      while(stack.length > 0){
        var temp = stack.shift();
        if(temp.x == xEnd && temp.y == yEnd){
          return temp.layer
        }
        x = temp.x + 1 ; y = temp.y;
        if(x == a) x = 0;
        if(newArr[x][y] != '#') {stack.push(new node(x , y , temp.layer + 1)) ; newArr[x][y] = '#'};
        //---------------
        x = temp.x - 1 ; y = temp.y;
        if(x == -1) x = a - 1;
        if(newArr[x][y] != '#') {stack.push(new node(x , y , temp.layer + 1)) ; newArr[x][y] = '#'};
        //-------------
        x = temp.x  ; y = temp.y + 1;
        if(y == a) y = 0;
        if(newArr[x][y] != '#') {stack.push(new node(x , y , temp.layer + 1)) ; newArr[x][y] = '#'};
        //-----------------
        x = temp.x  ; y = temp.y - 1;
        if(y == -1) y = a - 1;
        if(newArr[x][y] != '#') {stack.push(new node(x , y , temp.layer + 1)) ; newArr[x][y] = '#'};

      }
      return "-1"
    }
    var a = 5, arr = [[1, '#', 1, 1, 1], [1, 1, '#', 's', 1], [1, 'e', '#', '#', '#'], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
    fn(a, arr)


发表于 2020-07-08 17:16:49 回复(0)

最短路的搜索问题,可用广度优先搜索。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
int main()
{
    int N;
    while(cin>>N)
    {
        vector<string> g(N);
        string line;
        PII st,end;
        for(int i=0;i<N;i++)
        {
            cin>>line;
            for(int j=0;j<N;j++)
            {
                if(line[j]=='S')   st={i,j};
                if(line[j]=='E')    end={i,j};
            }
            g[i]=line;
        }
        //cout<<st.x<<" "<<st.y<<endl;
        queue<PII> q;
        q.push(st);
        int cnt=0;
        bool vis[N][N];
        memset(vis,0,sizeof vis);
        int dirs[5]={1,0,-1,0,1};
        vis[st.x][st.y]=true;
        bool flag=false;
        while(!q.empty())
        {
            int size=q.size();
            for(int i=0;i<size;i++)
            {
                auto cur=q.front(); q.pop();
                if(cur.x==end.x && cur.y==end.y)
                {
                    cout<<cnt<<endl;
                    flag=true;
                    break;
                }
                for(int k=0;k<4;k++)
                {
                    int ni=cur.x+dirs[k],nj=cur.y+dirs[k+1];
                    if(ni==-1) ni=N-1;
                    else if(ni==N) ni=0;
                    if(nj==-1) nj=N-1;
                    else if(nj==N) nj=0;
                    if(vis[ni][nj] || g[ni][nj]=='#') continue;
                    q.push({ni,nj});
                    vis[ni][nj]=true;
                }
            }
            cnt++;
        }
        if(!flag)
            cout<<-1<<endl;
    }
    return 0;
}
发表于 2020-09-05 18:55:16 回复(0)
BFS
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int n;
    static Character[][] chars;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = Integer.parseInt(sc.nextLine());
        chars = new Character[n][n];
        for (int i = 0; i < n; i++) {
            String line = sc.nextLine();
            for (int j = 0; j < n; j++) {
                chars[i][j] = line.charAt(j);
            }
        }
        int x = -1, y = -1, xEnd = -1, yEnd = -1;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (chars[i][j] == 'S') {
                    x = i;
                    y = j;
                }
                if (chars[i][j] == 'E') {
                    xEnd = i;
                    yEnd = j;
                }
            }
        }

        boolean[][] isVisited = new boolean[n][n];
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{x, y});
        isVisited[x][y] = true;

        int steps = 0;

        while (!queue.isEmpty()) {
            //记录当前层有多少节点
            int currentSize = queue.size();

            for (int i = 0; i < currentSize; i++) {
                int[] xy = queue.remove();
                if (xy[0] == xEnd && xy[1] == yEnd) {
                    System.out.println(steps);
                    return;
                }

                tryToMove(xy[0] + 1, xy[1], queue, isVisited);
                tryToMove(xy[0] - 1, xy[1], queue, isVisited);
                tryToMove(xy[0], xy[1] + 1, queue, isVisited);
                tryToMove(xy[0], xy[1] - 1, queue, isVisited);
            }
            steps++;
        }
        System.out.println(-1);
        return;
    }

    private static void tryToMove(int x, int y, Queue<int[]> queue, boolean[][] isVisited) {
        if (x < 0) x = n - 1;
        else if (x == n) x = 0;
        if (y < 0) y = n - 1;
        else if (y == n) y = 0;

        if (chars[x][y] != '#' && !isVisited[x][y]) {
            queue.add(new int[]{x, y});
            isVisited[x][y] = true;
        }
    }
}


发表于 2022-08-28 21:55:11 回复(0)
def ans(data):
    s_i = 0
    s_j = 0
    queue = []
    for i in range(len(data)):
        for j in range(len(data)):
            if data[i][j] == 'S':
                s_i = i
                s_j = j
                queue.append((s_i,s_j))
                break
    res = 0
    used = [[0]*len(data) for i in range(len(data))]
    used[s_i][s_j] = 1
    while queue:
        res += 1
        length = len(queue)
        for k in range(length):
            i,j = queue.pop(0)
            down = (i + 1 + len(data))%len(data)
            up = (i - 1 + len(data))%len(data)
            left = (j - 1 + len(data))%len(data)
            right = (j + 1 + len(data))%len(data)
            chance = [(up,j),(down,j),(i,left),(i,right)]
            for ii,jj in chance:
                if data[ii][jj] == "." and used[ii][jj] == 0:
                    queue.append((ii,jj))
                    used[ii][jj] = 1
                if data[ii][jj] == 'E':
                    return res
    return -1
    
if __name__ =="__main__":
    num = int(input())
    data = []
    for i in range(num):
        data.append(input())
    print(ans(data))
        

发表于 2022-08-06 15:05:31 回复(0)
import java.util.Scanner;

public class bishi {
    public static int min = Integer.MAX_VALUE;
    public static void main(String[] args) {//abcdab  aaabbcdefg
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
        String[][] strs = new String[num][num];
        for(int i = 0;i <num;i++){
            String string = sc.nextLine();
            for(int j = 0; j < num;j++){
                strs[i][j] = String.valueOf(string.charAt(j));
            }
        }
        for(int i = 0;i < num;i++){
            for(int j = 0;j < num;j++){
                if(strs[i][j].equals("S")){
                    int[][] flag = new int[num][num];
                    dfs(i,j,strs,flag,0);
                }
            }
        }
        min  = min == Integer.MAX_VALUE?-1:min;
        System.out.println(min);
    }
    public static void dfs(int i, int j, String[][] strs,int[][] flag,int index){
        i = i<0?strs.length+i:i;
        j = j<0?strs.length+j:j;
        i = i%strs.length;
        j = j%strs.length;
        if(strs[i][j].equals("#")||flag[i][j] == 1){
            return;
        }
        if(index >= min){
            return;
        }
        if(strs[i][j].equals("E")&&index!=0){
            min = index < min?index:min;
        }
        flag[i][j] = 1;
        dfs(i,j+1,strs,flag,index+1);
        dfs(i+1,j,strs,flag,index+1);
        dfs(i-1,j,strs,flag,index+1);
        dfs(i,j-1,strs,flag,index+1);
        flag[i][j] = 0;
    }
}
//5
//        .#...
//        ..#S.
//        .E###
//        .....
//        .....

发表于 2022-04-17 15:54:48 回复(0)
import java.util.Scanner;
import java.util.Queue;
import java.util.LinkedList;

class Node{
    public int x;
    public int y;
    public int value;
    public Node(int x,int y,int value){
        this.x=x;
        this.y=y;
        this.value=value;
    }
}
public class Main{
    // ------1-------
    static int[]xx=new int[]{0,0,-1,1};
    static int[]yy=new int[]{-1,1,0,0};
    static int sx=0;
    static int sy=0;
    static int ex=0;
    static int ey=0;
    static int n=-1;
    public static void main(String[] args){
        //------2-------
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        sc.nextLine();
        boolean[][]vis=new boolean[n][n];
        char[][] map =new char[n][n];
        for(int i=0;i<n;i++){
            String line=sc.nextLine();
            for(int j=0;j<n;j++){
                map[i][j]=line.charAt(j);
                if(map[i][j]=='S'){ sx=i;sy=j;}
                if(map[i][j]=='E'){ ex=i;ey=j;}
            }
        }
        sc.close();
        if(sx == -1 && sy == -1)     System.out.println("-1");
        if(ex == -1 && ey == -1)     System.out.println("-1");
        int re=bfs(map,vis);// 求最短路径问题
        System.out.println(re);
    }
    // 标准bfs
    public static int bfs(char[][] map, boolean [][]vis){
        Queue <Node> queue=new LinkedList<Node>();
        queue.offer(new Node(sx,sy,0));
        vis[sx][sy]=true;//  sx和sy只是初始的时候用到了
        while(!queue.isEmpty()){
            Node node=queue.poll();
            for(int i=0;i<4;i++){
                int nx=(xx[i]+node.x+n)%n;      //此时用x不行的
                int ny=(yy[i]+node.y+n)%n;
                if(check(map,vis,nx,ny)){ continue; }
                if(nx==ex&&ny==ey){return node.value+1;}
                vis[nx][ny]=true;
                queue.offer(new Node(nx,ny,node.value+1));
            }
        }
        return -1;
    }
    // 判断函数
    public static boolean check(char[][] map,boolean[][]vis,int x,int y){
        if(map[x][y]=='#'||vis[x][y]==true){
            return true;
        }
        return false;
    }
}


发表于 2021-03-25 16:08:47 回复(0)
//层序遍历,求深度
#include<iostream>
#include<vector>
#include <queue>
using namespace std;
int main()
{
    int n=0;
    cin>>n;
    vector<vector<char>> mp(n,vector<char>(n,0));
    string tmp;
    int x,y;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            cin>>mp[i][j];
           if(mp[i][j]=='S') 
           {
               x=i;
               y=j;
           }
        }
    //获取数据结束
    queue<pair<int, int>> steps;
    steps.push({x,y});
    int res=0;
    int X[]={0,0,1,-1};
    int Y[]={1,-1,0,0};
    bool findE=false;
    while(!steps.empty())
    {
        int sz=steps.size();
        if(sz) res++;
        while(sz--)
        {
            x=steps.front().first;
            y=steps.front().second;
            steps.pop();
            for(int i=0;i<4;i++)
            {
                int x_next=x+X[i];
                int y_next=y+Y[i];
                x_next=x_next>=n?0:(x_next<0?(n-1):x_next);
                y_next=y_next>=n?0:(y_next<0?(n-1):y_next);
                if(mp[x_next][y_next]=='E')
                {
                    findE=true;
                    break;
                }
                if(mp[x_next][y_next]=='.')
                {
                    steps.push({x_next,y_next});
                    mp[x_next][y_next]='#';
                }
            }//方向循环
            if(findE) break;
           
        }//每一层
        if(findE) break;
    }
    if(findE) cout<<res<<endl;
    else cout<<-1<<endl;
    return 0;
}

发表于 2020-12-14 22:09:14 回复(0)
想问问大佬怎么改……一直提示我段错误,但是我是真不知道怎么改了,求大佬看看我QAQ
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

const int maxn = 10001;
char matrix[maxn][maxn];
bool inq[maxn][maxn] = {false};

int X[4] = {0, 0, 1, -1};
int Y[4] = {1, -1, 0, 0};

struct node
{
    int x, y;
    int step; //从起点S到达该位置的最少步数
}S, E, Node;//S为起点, E为终点, Node为临时结点

bool isValid(int x, int y)
{
    if(matrix[x][y] == '#') return false;
    if(inq[x][y]) return false;
    return true;
}
int BFS(int n)
{
    queue<node> q;
    q.push(S);
    inq[S.x][S.y] = true;
    while(!q.empty())
    {
        node top = q.front();
        q.pop();

        if(top.x == E.x && top.y == E.y)
        {
            return top.step;
        }

        for(int i = 0; i < 4; i++)
        {
            Node.x = (top.x + X[i]) % n;
            Node.y = (top.y + Y[i]) % n;
            if(isValid(Node.x, Node.y))
            {
                Node.step = top.step + 1;
                q.push(Node);
                inq[Node.x][Node.y] = true;
            }
        }
    }
    return -1;
}
int main(){
    int n;
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 0; i < n; i++)
        {
            getchar(); //过滤掉每行的换行符
            for(int j = 0; j < n; j++)
            {
                matrix[i][j] = getchar();
                if(matrix[i][j] == 'S')
                {
                    S.x = i;
                    S.y = j;
                    S.step = 0;
                }
                if(matrix[i][j] == 'E')
                {
                    E.x = i;
                    E.y = j;
                }
            }
            matrix[i][n] = 0;
        }

        printf("%d\n", BFS(n));
        memset(inq, 0, sizeof(bool) * n);
        fflush(stdin);
    }

    return 0;
}

发表于 2020-09-24 12:03:22 回复(3)
深搜过了50%,应该是深搜复杂度过高
import java.util.Scanner;

public class bishi {
    public static int min = Integer.MAX_VALUE;
    public static void main(String[] args) {//abcdab  aaabbcdefg
        Scanner sc = new Scanner(System.in);
        int num = Integer.parseInt(sc.nextLine());
        String[][] strs = new String[num][num];
        for(int i = 0;i <num;i++){
            String string = sc.nextLine();
            for(int j = 0; j < num;j++){
                strs[i][j] = String.valueOf(string.charAt(j));
            }
        }
        for(int i = 0;i < num;i++){
            for(int j = 0;j < num;j++){
                if(strs[i][j].equals("S")){
                    int[][] flag = new int[num][num];
                    dfs(i,j,strs,flag,0);
                }
            }
        }
        min  = min == Integer.MAX_VALUE?-1:min;
        System.out.println(min);
    }
    public static void dfs(int i, int j, String[][] strs,int[][] flag,int index){
        i = i<0?strs.length+i:i;
        j = j<0?strs.length+j:j;
        i = i%strs.length;
        j = j%strs.length;
        if(strs[i][j].equals("#")||flag[i][j] == 1){
            return;
        }
        if(index >= min){
            return;
        }
        if(strs[i][j].equals("E")&&index!=0){
            min = index < min?index:min;
        }
        flag[i][j] = 1;
        dfs(i,j+1,strs,flag,index+1);
        dfs(i+1,j,strs,flag,index+1);
        dfs(i-1,j,strs,flag,index+1);
        dfs(i,j-1,strs,flag,index+1);
        flag[i][j] = 0;
    }
}
//5
//        .#...
//        ..#S.
//        .E###
//        .....
//        .....


发表于 2020-09-14 16:13:38 回复(0)

分析

使用BFS从开始节点S向外围搜索,通过类似于树的层次级遍历的方法,使用队列queue.deque存储当前层的节点坐标,并逐个取出来再向外层扩展。注意在添加新的节点到队列过程中要设定新节点为‘#’,不然在下一轮的搜索中这个节点会被重复搜索,从而导致在一些case上超时。

from queue import deque

def bfs(matrix, i, j, N):
    length = 0
    que = deque()
    que.append((i, j))
    while que:
        length += 1
        # 遍历当前层的所有节点
        for _ in range(len(que)):
            x, y = que.popleft()
            for dx, dy in [[-1, 0], [1, 0], [0, 1], [0, -1]]:
                new_x = (x + dx) % N
                new_y = (y + dy) % N
                if matrix[new_x][new_y] == 'E':
                    return length
                elif matrix[new_x][new_y] != '#':
                    #提前设定为障碍,避免重复访问
                    matrix[new_x][new_y] = '#'
                    que.append((new_x, new_y))
    return -1

def main():
    N = int(input())
    matrix = [[None for _ in range(N)] for _ in range(N)]
    for i in range(N):
        matrix[i] = list(input())

    for i in range(N):
        for j in range(N):
            if matrix[i][j] == 'S':
                return bfs(matrix, i, j, N)
    return -1
print(main())
发表于 2020-07-06 22:31:58 回复(0)
从别处看的一个版本,有点不明白每次都要四个方向试一遍吗?这段代码是如何保证走的是最短路径?有点晕(((φ(◎ロ◎;)φ)))
importjava.util.Scanner;
importjava.io.File;
importjava.util.Queue;
importjava.util.LinkedList;
 
classNode{
    publicintx;
    publicinty;
    publicintlayer;
    publicNode(intx,inty,intlayer) {
        this.x = x;
        this.y = y;
        this.layer = layer;
    }
}
publicclassMain {
    publicstaticvoidmain(String[] args)throwsException{
        //File file = new File("in.txt");
        //Scanner in = new Scanner(file);
        Scanner in =newScanner(System.in);
        intn = in.nextInt();
        in.nextLine();
        char[][] board =newchar[n][n];
        intstartX = -1;intstartY = -1;
        intendX = -1;intendY = -1;
        for(inti =0; i < n; i++) {
            String line = in.nextLine();
            for(intj =0; j < n; j++) {
                board[i][j] = line.charAt(j);
                if(board[i][j] =='S') {
                    startX = i;
                    startY = j;
                }elseif(board[i][j] =='E') {
                    endX = i;
                    endY = j;
                }
            }
        }
        in.close();
        if(startX == -1&& startY == -1) System.out.println("-1");
        if(endX == -1&& endY == -1) System.out.println("-1");
         
        Queue<Node> queue =newLinkedList<Node>();
        intx = -1;inty = -1;
        queue.offer(newNode(startX, startY,0));
        while(!queue.isEmpty()) {
            Node node = queue.poll();
             
            //找到最后结果
            if(node.x == endX && node.y == endY) {
                System.out.println(node.layer);
                return;
            }
 
            //四个方向
            x = node.x +1; y = node.y;
            if(x == n) x =0;
            if(board[x][y] !='#') {queue.offer(newNode(x, y, node.layer +1)); board[x][y] ='#';}
 
            x = node.x -1; y = node.y;
            if(x == -1) x = n-1;
            if(board[x][y] !='#') {queue.offer(newNode(x, y, node.layer +1)); board[x][y] ='#';}
 
            x = node.x; y = node.y +1;
            if(y == n) y =0;
            if(board[x][y] !='#') {queue.offer(newNode(x, y, node.layer +1)); board[x][y] ='#';}
 
            x = node.x; y = node.y -1;
            if(y == -1) y = n-1;
            if(board[x][y] !='#') {queue.offer(newNode(x, y, node.layer +1)); board[x][y] ='#';}
        }
        System.out.println("-1");
    }
}
发表于 2020-07-01 23:22:58 回复(0)
def getInput():
    s = input().strip()
    n = int(s)
 
    data = []
    for i in range(n):
        s = input().strip()
        data.append(list(s))
 
    return n, data
 
def main(n, data):
    if n < 2:
        return -1
    si = -1
    sj = -1
    for i in range(n):
        for j in range(n):
            if data[i][j] == 'S':
                si = i
                sj = j
                break
        if si != -1:
            break
    data[si][sj] = '#'
 
 
    queue = [[si, sj, 0]]
    while len(queue) > 0:
        i, j, step = queue.pop(0)
        for add_i, add_j in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
            next_i = i + add_i
            next_i = adjust(next_i, n)
            next_j = j + add_j
            next_j = adjust(next_j, n)
            if data[next_i][next_j] != '#':
                if data[next_i][next_j] == 'E':
                    return step + 1
                data[next_i][next_j] = '#'
                queue.append([next_i, next_j, step + 1])
    return -1
 
 
def adjust(x, n):
    if x < 0:
        return n - 1
    if x == n:
        return 0
    return x
 
n, data = getInput()
# n = 5
# s = '.#... ..#S. .E###  ..... .....'
# s_list = s.split()
# data = [list(s) for s in s_list]
ans = main(n, data)
print(ans)

发表于 2020-06-27 23:25:06 回复(0)
//为啥我这么长,别人都短,我怕是个傻子吧
#include<iostream>
#include<string>
#include<vector>
#include<queue>
using namespace std;
 
struct Point{
    int i;
    int j;
    Point(){}
    Point(int _i,int _j):i(_i),j(_j){}
};
 
class Solution{
    public:
       int getMinNum(vector<string> str,vector<bool> visited){
           if(str.size() == 0 || str[0].size() == 0){
               return -1;
           }
           int N = str[0].size();
           //1.找到SE
           int si,sj;
           int ei,ej;
           for(int i=0;i<str.size();i++){
               for(int j=0;j<str[0].size();j++){
                   if(str[i][j] == 'S'){
                       si = i;
                       sj = j;
                   }
                   if(str[i][j] == 'E'){
                       ei = i;
                       ej = j;
                   }
               }
           }
           // 边界 -1,N
           queue<Point> que;
           que.push(Point(si,sj));
           visited[si*N + sj] = true;
           int count = 0;
           bool flag = false;
           while(!que.empty()){
               int len = que.size();
               for(int i=0;i<len;i++){//
                   Point temp = que.front();
                   que.pop();
                   if(temp.i == ei && temp.j == ej){
                       flag =true;
                       break;
                   }
                   //上面 i-1 ,j
                   if(temp.i != 0 && str[temp.i-1][temp.j] != '#' && !visited[(temp.i-1)*N +temp.j]){
                       que.push(Point(temp.i-1,temp.j));
                       visited[(temp.i-1)*N +temp.j] = true;
                   }
                   if(temp.i == 0 && str[N-1][temp.j] != '#' && !visited[(N-1)*N + temp.j]){
                       que.push(Point(N-1,temp.j));
                       visited[(N-1)*N + temp.j] = true;
                   }
                   // 右面 i , j+1
                   if(temp.j != N-1 && str[temp.i][temp.j+1] != '#' && !visited[(temp.i)*N + temp.j+1]){
                       que.push(Point(temp.i,temp.j+1));
                       visited[(temp.i)*N + temp.j+1] = true;
                   }
                   if(temp.j == N-1 && str[temp.i][0] != '#' && !visited[temp.i * N + 0]){
                       que.push(Point(temp.i,0));
                       visited[temp.i * N + 0] = true;
                   }
                   //下面 i+1,j
                   if(temp.i != N-1 && str[temp.i + 1][temp.j] != '#' &&  !visited[(temp.i+1)*N + temp.j]){
                       que.push(Point(temp.i+1,temp.j));
                       visited[(temp.i+1)*N + temp.j] = true;
                       
                   }
                   if(temp.i == N-1 && str[0][temp.j] != '#' && !visited[0*N + temp.j]){
                       que.push(Point(0,temp.j));
                       visited[0*N + temp.j] = true;
                   }
                   //左面 i,j-1
                   if(temp.j != 0 && str[temp.i][temp.j -1] != '#' && !visited[temp.i *N + temp.j-1]){
                       que.push(Point(temp.i,temp.j-1));
                       visited[temp.i *N + temp.j-1] = true;
                       
                   }
                   if(temp.j == 0 && str[temp.i][N-1] != '#' && !visited[temp.i*N + N-1]){
                       que.push(Point(temp.i,N-1));
                       visited[temp.i*N + N-1] = true;
                   }
                    
               }
               if(flag == true){
                   break;
               }
               count++;
           }
           if(que.empty() && flag == false){
               return -1;
           }
           
           return count;
       }
      
};
 
int main(){
    int n;
    cin>>n;
    vector<string> arr;
    string str;
    for(int i=0;i<n;i++){
        cin>>str;
        arr.push_back(str);
    }
    Solution c1;
    vector<bool> visited(arr.size()*arr.size(),false);
    cout<<c1.getMinNum(arr,visited)<<endl;
    return 0;
     
     
}

发表于 2020-06-14 21:09:29 回复(1)
def f():
    N = int(input())
    ls = []
    for i in range(N):
        ls.append(list(input()))
    flag = [[0]*N for i in range(N)]
    for i in range(N):
        for j in range(N):
            if ls[i][j] == 'S':
                start = [i,j]
            if ls[i][j] == 'E':
                end = [i,j]
            if ls[i][j] == '#':
                flag[i][j] = 0
    dir = [(1,0),(0,1),(-1,0),(0,-1)]
    flag[start[0]][start[1]] = 1
    xy = [[start[0],start[1]]]
    step = 0
    while xy:
        tmp_ls = []
        for index in xy:
            i,j = index
            for d in dir:
                new_i = i+d[0]
                new_j = j+d[1]
                if new_i==N:new_i = 0
                elif new_i==-1:new_i = N-1
                if new_j == N:new_j = 0
                elif new_j == -1:new_j = N-1
                if [new_i,new_j] == end:
                    return step+1
                if ls[new_i][new_j]!='#' and flag[new_i][new_j]==0:
                    flag[new_i][new_j] = 1
                    tmp_ls.append([new_i,new_j])
        xy = tmp_ls
        step+=1
    return -1
print(f())
BFS
发表于 2020-06-12 11:16:20 回复(0)

迷宫游戏 小红书 golang bfs

看到大家的程序都很繁琐我就放心了。

基本思路就是bfs,将起点放进待处理的队列,每次出队一个元素,将其相邻的可行元素入队。
可以取消 打印生长过程 的注释,当图生长碰到终点,就输出长度,如果知道结束都没有碰到终点则输出-1.

package main

import (
    "fmt"
)

func main() {
    var n int
    var s [2]int
    var in string
    //标记矩阵
    var mapp [][]int
    fmt.Scan(&n)
    for i:=0;i<n;i++{
        fmt.Scan(&in)
        line:=[]int{}
        for j,v:=range in{
            switch v {
            case '.':
                line = append(line, 1)
            case '#':
                line = append(line, 0)
            case 'S':
                s=[2]int{i,j}
                line = append(line, 9)
            case 'E':
                //e=[2]int{i,j}
                line = append(line, 2)
            }
        }
        mapp = append(mapp, line)
    }
    //列数
    w:= len(mapp[0])
    d:=[4][2]int{{1,0},{-1,0},{0,1},{0,-1}}
    //待处理的点的队列
    queue:=[][2]int{s}
    steps,lenz:=1,1
    reachable:=false
    for i:=0;i< len(queue)&&!reachable;i++{
        if i==lenz{
            steps++
            lenz= len(queue)
            //打印生长过程
            //for _,v:=range mapp{
            //    fmt.Println(v)
            //}
            //fmt.Println("-------",steps,"-----")
            //fmt.Println()
        }
        x,y:=queue[i][0],queue[i][1]
        for i:=0;i<4;i++{
            //注意考虑溢出
            xx,yy:=(x+d[i][0]+w)%w,(y+d[i][1]+w)%w
            switch mapp[xx][yy] {
            //可以走的点标记为9
            case 1:
                mapp[xx][yy]=9
                queue = append(queue, [2]int{xx,yy}) 
            //发现终点提前结束
            case 2:
                reachable=true
                break
            }
        }
    }
    if reachable{
        fmt.Println(steps)
    }else {
        fmt.Println(-1)
    }
}
发表于 2020-06-09 15:58:45 回复(0)
#include <iostream>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <ctype.h>
#include <string>
#include <cstring>
#include <cstdio>
#include <set>
#include <cstdio>
#include <fstream>
#include <deque>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <iomanip>
#define SIS std::ios::sync_with_stdio(false)
#define ll long long
#define INF 0x3f3f3f3f
const int mod = 1e9 + 7;
const double esp = 1e-5;
const double PI = 3.141592653589793238462643383279;
using namespace std;
const int N = 1e7 + 5;
const int maxn = 1 << 20;
ll powmod(ll a, ll b) { ll res = 1; a %= mod; while (b >= 0); for (; b; b >>= 1) { if (b & 1)res = res * a % mod; a = a * a % mod; }return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
/*void chafen(int l, int r, int k) {//差分函数
    p[l] += k;
    p[r + 1] -= k;
}*/
/*********************************************************/
bool vis[1005][1005];
char a[1005][1005];
int x[4] = { -1,0,1,0 };
int y[4] = { 0,1,0,-1 };
int u1=-1, v1=-1, u2=-1, v2=-1;
int n, m;
struct node {
    int x;
    int y;
    int step;
};

int convert(int num,int n){
    if(num==-1) return  n-1;
    if(num==n)  return 0;
    return num;
}

int bfs() {
    if(u1==-1 || u2==-1)    return -1;
    queue<node> q;
    node p;//起点
    p.x = u1; p.y = v1;
    p.step = 0;
    q.push(p);
    a[u1][v1]='#';
    while (!q.empty()) {
        node p1 = q.front();
        q.pop();
        node t;
        for (int i = 0; i < 4; i++) {
            t.x = p1.x + x[i] ;
            t.x = convert(t.x,n);
            t.y = p1.y + y[i] ;
            t.y = convert(t.y,n);
            t.step = p1.step + 1;
            if (a[t.x][t.y]!='#') {
                if (a[t.x][t.y]=='E')
                    return t.step;
                else a[t.x][t.y]='#';
                q.push(t);
            }
        }
    }
    return -1;
}
int main()
{
    cin >> n ;
    m = n;
    memset(vis, false, sizeof(vis));
    for (int i = 0; i < n; i++) {
        getchar();
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
            if (a[i][j] == 'S') {
                u1 = i;
                v1 = j;
            }
            if (a[i][j] == 'E') {
                u2 = i;
                v2 = j;
            }
        }
    }
    cout << bfs() << endl;
    return 0;
}
/*
5 5
.....
.*.*.
.*S*.
.***.
...T*
*/


发表于 2020-06-09 01:20:46 回复(1)