P1363---幻象迷宫

简介: P1363---幻象迷宫

题目描述


(喵星人LHX和WD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫。)


WD:呜呜,肿么办啊……


LHX:momo…我们一定能走出去的!


WD:嗯,+U+U!


描述 Description


幻象迷宫可以认为是无限大的,不过它由若干个N*M的矩阵重复组成。矩阵中有的地方是道路,用’.‘表示;有的地方是墙,用’#‘表示。LHX和WD所在的位置用’S’表示。也就是对于迷宫中的一个点(x,y),如果(x mod n,y mod m)是’.‘或者’S’,那么这个地方是道路;如果(x mod n,y mod m)是’#’,那么这个地方是墙。LHX和WD可以向上下左右四个方向移动,当然不能移动到墙上。


请你告诉LHX和WD,它们能否走出幻象迷宫(如果它们能走到距离起点无限远处,就认为能走出去)。如果不能的话,LHX就只好启动城堡的毁灭程序了……当然不到万不得已,他不想这么做。。。


20210607191325138.png

输入1

5 4
##.#
##S#
#..#
#.##
#..#
5 4
##.#
##S#
#..#
..#.
#.##

输出1

Yes
No

思路:题目的要求是看能否走出迷宫,也就是能够走到无限远处,如果走到某个点后现在又回到了这个点,则说明是可以走到无限远的.

如何进行判断是否走到过这个点呢?

每次记录取模的横纵坐标x,y,同时记录没有取模的坐标lx,ly.

lx,ly相当于是实际走时的坐标,x,y是相对于原来的地图中的坐标,因为整个大地图是原来小地图的无限扩展.

当第一次走到这个迷宫的时候,x,y和lx,ly肯定是分别相等的.

所以如果只要走到的一个点x,y和lx,ly不相等而且x,y被走过,则说明走进了两个同的小图.则这个点就是被走了两遍.

思路没啥问题,运行会出错,可能数据量太大了.之后有时间了再看看其他做法.


参考代码

#include<iostream>
#include<string.h>
using namespace std;
const int maxn = 1510;
int map[maxn][maxn],vis[maxn][maxn][3],n,m,flag;
int NEXT[4][2] = {
  0,-1,
  1,0,
  0,1,
  -1,0
};//方向数组
void dfs(int x,int y,int lx,int ly) {
  if(flag) {
    return;
  }
  if((vis[x][y][1]!=lx||vis[x][y][2]!=ly)&&vis[x][y][0]) { //结束条件 上次到这个未知的lx,ly和这次到这个位置 lx,ly不一样则说明该处已经被访问过两次了.
    flag = 1;
    return;
  }
  vis[x][y][1] = lx;
  vis[x][y][2] = ly;
  vis[x][y][0] = 1;
  for(int i = 0; i < 4; i++) {
    int xx = (x+NEXT[i][0]+n)%n;
    int yy = (y+NEXT[i][1]+m)%m;
    int lxx = lx+NEXT[i][0];
    int lyy = ly + NEXT[i][1];
    if(!map[xx][yy]) { //如果不是墙
      if(vis[lxx][lyy][1]!=lxx || vis[lxx][lyy][2] != lyy || !vis[lxx][lyy][0]) {
        dfs(xx,yy,lxx,lyy);
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  char ch;
  int s_x,s_y;
  while(cin>>n>>m) {
    //数据初始化
    memset(map,0,sizeof(map));
    memset(vis,0,sizeof(vis));// 0表示道路 
    flag = 0;
    for(int i = 0; i < n; i++) {
      for(int j = 0; j< m; j++) {
        cin>>ch;
        if(ch=='#') {
          map[i][j] = 1;//表示墙  1
        }
        if(ch=='S') {
          s_x = i;
          s_y = j;
        }
      }
    }
    dfs(s_x,s_y,s_x,s_y);
    if(flag) {
      cout<<"Yes"<<endl;
    } else {
      cout<<"No"<<endl;
    }
  }
  return 0;
}
相关文章
|
6月前
poj 3984 迷宫问题(BFS+输出路径)
poj 3984 迷宫问题(BFS+输出路径)
27 0
LeetCode 1812. 判断国际象棋棋盘中一个格子的颜色
给你一个坐标 coordinates ,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。下图是国际象棋棋盘示意图。
121 0
|
测试技术
|
机器学习/深度学习
【每日一题Day50】LC1812判断国际象棋棋盘中一个格子的颜色 | 找规律
【每日一题Day50】LC1812判断国际象棋棋盘中一个格子的颜色 | 找规律
75 0
递归题目练习---数独问题
递归题目练习---数独问题
110 0
递归题目练习---数独问题
|
算法
递归题目练习---N皇后问题
递归题目练习---N皇后问题
108 0
递归题目练习---N皇后问题
|
算法
动态规划---数字三角形模型(二)
AcWing算法提高课内容,本文讲解 动态规划
114 0
动态规划---数字三角形模型(二)