• 洛谷P1363 幻想迷宫【dfs】


    题目https://www.luogu.org/problemnew/show/P1363

    题意

    有一个地图,起点是S,障碍物用#表示。可以将这个地图不断的在四周重复,问从起点开始是否可以走到无限远的地方去。

    思路

    刚开始想的是地图放中间,然后在四周都拼一个同样的,然后看看能不能走回到起点。

    但是发现仅仅是拼四个是不够的,那拼九个?反正又是MLE又是WA的。

    主要思路还是dfs搜索,题目中其实给了提示了,可以利用取模。

    把每一次走的位置都压缩到一个地图上去。但是又去标记这是在那一块被访问到的。

    如果可以两次走到这个点(其实并不是走到这个点而是走到另一块的对应位置)就说明可以走到无限远的地方。

    所以我们需要个vis数组。第一个用来标记这个点是否被访问过,第二三个用来标记访问到对应这个点时候的横纵坐标。

    dfs时即需要知道当前的坐标,又需要知道取模之前实际的坐标。

    如果之前走到这个点时候的横纵坐标和现在实际的坐标是相同的,说明走到的是同一个点,如果有一个是不同的说明已经走到另一块地图上去了。

     1 //#include<bits/stdc++>
     2 #include<stdio.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<stdlib.h>
     7 #include<queue> 
     8 #include<map>
     9 #include<stack>
    10 #include<set>
    11 
    12 #define LL long long
    13 #define ull unsigned long long
    14 #define inf 0x7f7f7f7f 
    15 
    16 using namespace std;
    17 
    18 int n, m;
    19 const int maxn = 1505;
    20 char gra[maxn][maxn];
    21 int vis[maxn][maxn][3];
    22 int dx[4] = {0, 0, -1, 1};
    23 int dy[4] = {1, -1, 0, 0};
    24 int stx, sty;
    25 
    26 bool check(int x, int y)
    27 {
    28     if(x < 0 || y < 0 || x >= n || y >= m)return false;
    29     else return true;
    30 }
    31 
    32 bool ans;
    33 void dfs(int x, int y, int acx, int acy)
    34 {
    35     if(vis[x][y][0] && vis[x][y][1] == acx && vis[x][y][2] == acy){
    36         
    37         return;
    38     }
    39     else if(vis[x][y][0] && (vis[x][y][1] != acx || vis[x][y][2] != acy)){
    40         ans = true;
    41         return;    
    42     }
    43     vis[x][y][0] = true;
    44     vis[x][y][1] = acx;
    45     vis[x][y][2] = acy;
    46     for(int i = 0; i < 4; i++){
    47         int tox = (x + dx[i] + n) % n, toy = (y + dy[i] + m) % m;
    48         if(check(tox, toy) && gra[tox][toy] != '#'){
    49             dfs(tox, toy, acx + dx[i], acy + dy[i]);
    50         }
    51     }
    52     return;
    53 }
    54 
    55 int main()
    56 {
    57     while(scanf("%d%d", &n, &m) != EOF){
    58         memset(gra, 0, sizeof(gra));
    59         memset(vis, 0, sizeof(vis));
    60         ans = false;
    61         for(int i = 0; i < n; i++){
    62             cin>>gra[i];
    63             for(int j = 0; j < m; j++){
    64                 if(gra[i][j] == 'S'){
    65                     stx = i;
    66                     sty = j;
    67                 }
    68             }
    69         }
    70         
    71         dfs(stx, sty, stx, sty);//vis[stx][sty][0] = true;
    72         if(ans)printf("Yes
    ");
    73         else printf("No
    ");
    74     }
    75     
    76     return 0;    
    77 } 
  • 相关阅读:
    JavaScript 原型和原型链 prototype
    javascript dom 表单元素之 radio
    JavaScript Dom 表单元素之 checkbox
    JavaScript DOM 表单元素之 select
    JavaScript-ECMAScript 之模块
    Javascript--ECMAScript 之 this
    Javascript-ECMAscript--Array.prototype.slice() 方法
    JavaScript -ECMAScriopt: Array.prototype.slice.call()详解及转换数组的方法
    JavaScript-ECMASCript apply call bind
    requests的深入刨析及封装调用
  • 原文地址:https://www.cnblogs.com/wyboooo/p/10960351.html
Copyright © 2020-2023  润新知