列表

详情


NC14118. Certain Maze

描述

最近,无聊的过河船同学发现了一种无聊的迷宫生成算法。
算法过程如下: 一个N * M的矩形区域可以看作N * M个单位网格组成。在每个网格中,随机生成一个从右上角到左下角的L型障碍或者从左上角到右下角的R型障碍(障碍可以被看作一条线段)。

图1:两种障碍
这样便可以生成一个大小为N * M的迷宫,如图2所示。

图2:无聊的迷宫
然后过河船同学想知道,是否存在迷宫内的从迷宫上边界到达迷宫的下边界的路径。于是无聊的过河船同学花了一夜的时间,终于找到一条路径。

图3:过河船同学辛辛苦苦找到的道路
痛苦的过河船同学不想再伤害自己的眼睛,他想直接知道,对于给定的迷宫,是否存在这样的路径。
请注意,路径只能从迷宫内部穿过,除起点和终点外不得离开迷宫区域。

输入描述

第一行是一个正整数T(≤ 1000),表示测试数据的组数,
对于每组测试数据,
第一行是两个整数N(1≤ N ≤ 100)和M(1 ≤ M ≤ 100),表示迷宫的行数和列数,
接下来N行,每行是一个长为M的只包含'L'和'R'的字符串,'L'表示一个L型障碍,'R'表示一个R型障碍。

输出描述

对于每组测试数据,如果存在一条可以从迷宫的上边界到达迷宫的下边界的路径,输出"Yes"(不含引号),否则输出"No"(不含引号)。

示例1

输入:

2
2 2
LR
LR
2 2
LL
RR

输出:

No
Yes

说明:


原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 132ms, 内存消耗: 620K, 提交时间: 2020-05-25 17:55:09

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
const int M = 10100;

int t, n, m;
char a[N][N];
struct Node {
    int v, nxt;
}edge[M * 3];

int cnt, head[M];
bool vis[M];

void init()
{
    cnt = 0;
    memset(head, -1, sizeof head);
    memset(vis, false, sizeof vis);
}
void add(int x, int y)
{
  //  cout << x/m << ' ' <<x%m << ' ' << y /m<<' ' << y%m<<endl;
    edge[cnt].v = y; edge[cnt].nxt = head[x]; head[x] = cnt++;
    edge[cnt].v = x; edge[cnt].nxt = head[y]; head[y] = cnt++;
}
bool bfs()
{
    queue<int> que;
    for(int i = 0; i < m; i++) que.push(i), vis[i] = true;

    while(!que.empty()) {
        int h = que.front(); que.pop();

        if(h >= n * m) return true;

        for(int i = head[h], v; ~i; i = edge[i].nxt) {
            v = edge[i].v;
            if(!vis[v]) {
                vis[v] = true;
                que.push(v);
            }
        }
    }

    return false;
}

int main()
{
    //freopen("data.txt", "r", stdin);
    scanf("%d", &t);

    bool ans;
    while(t--) {
        init();

        scanf("%d%d", &n, &m);

        for(int i = 0; i < n; i++) {
            scanf("%s", a[i]);
        }

        for(int i = 0; i < n; i++) {
            for(int j = 1; j < m; j++) {
                if(a[i][j] == 'L') {
                    if(a[i][j-1] == 'L') add(i*m+j, (i+1)*m+j-1);
                    else add(i*m+j, i*m+j-1);
                }
                else {
                    if(a[i][j-1] == 'L') add((i+1)*m+j, (i+1)*m+j-1);
                    else add(i*m+j-1, (i+1)*m+j);
                }
            }
        }

        if(bfs()) printf("Yes\n");
        else printf("No\n");
    }

    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 907ms, 内存消耗: 2136K, 提交时间: 2019-05-09 21:09:18

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[510][510];
char ch[110];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int dfs(int x,int y){
    if(a[x][y]||x<1||x>n||y<1||y>m) return 0;
    if(x==n) return 1;
    a[x][y]=1;
    for(int i=0;i<4;i++) if(dfs(x+dx[i],y+dy[i])) return 1;
    return 0;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",ch+1);
            for(int j=1;j<=m;j++){
                if(ch[j]=='L') a[i*5-4][j*5]=a[i*5-3][j*5-1]=a[i*5-2][j*5-2]=a[i*5-1][j*5-3]=a[i*5][j*5-4]=1;
                if(ch[j]=='R') a[i*5-4][j*5-4]=a[i*5-3][j*5-3]=a[i*5-2][j*5-2]=a[i*5-1][j*5-1]=a[i*5][j*5]=1;
            }
        }
        n*=5,m*=5;
        int bl=0;
        for(int i=1;i<=m;i++){
            if(dfs(1,i)){
                printf("Yes\n");
                bl=1;
                break;
            }
        }
        if(!bl) printf("No\n");
    }
    return 0;
}

上一题