Mirror Maze

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

There is an n×mn\times mn×m mirror maze, where there is a mirror on each grid. The mirrors are in one of the following four types:

  • ``-'', the light from above or below will be reflected back, the light from left or right will continue going forward without being reflected, respectively;
  • ``|'', the light from left or right will be reflected back, the light from above or below will continue going forward without being reflected, respectively;
  • ``/'', the light from left, right, above, below will be reflected to go above, below, left, right, respectively;
  • ``\\backslash\'', the light from left, right, above, below will be reflected to go below, above, right, left, respectively.

Now there are qqq light sources. Little G, the believer of the light, wants to know the numbers of different mirrors the emitted light will be reflected by within sufficient time for each light source.

输入描述:

The first line contains two integers n,m (1≤n,m≤1 000)n,m\,(1 \le n,m \le 1\,000)n,m(1≤n,m≤1000), denoting the size of the mirror maze.

Each of the following nnn lines contains a string of length mmm, where the jjj-th character in the iii-th line Si,j (Si,j∈{∣,−,/,\})S_{i,j}\,(S_{i,j} \in \{|, -, /, \backslash\})Si,j​(Si,j​∈{∣,−,/,\}) denotes the mirror on grid (i,j)(i,j)(i,j).

The next line contains an integer q (1≤q≤105)q\,(1 \le q \le 10^5)q(1≤q≤105), denoting the number of light sources.

Each of the following qqq lines contains two integers u (1≤u≤n)u\,(1 \le u \le n)u(1≤u≤n), v (1≤v≤m)v\,(1 \le v \le m)v(1≤v≤m) and a string dir (dir∈{above,below,left,right})dir\,(dir \in \{above, below, left, right\})dir(dir∈{above,below,left,right}), denoting that a light source is on grid (u,v)(u,v)(u,v) and emits light going along the dirdirdir direction. Specifically, the light will not be influenced by the mirror on grid (u,v)(u,v)(u,v) initially.

输出描述:

Output qqq lines each containing one integer, denoting the number of different mirrors the emitted light will be reflected by within sufficient time for each light source.

示例1

输入

复制2 3 /\- \/| 2 1 2 below 2 2 right

2 3
/\-
\/|
2
1 2 below
2 2 right

输出

复制4 2

4
2

说明

· For the first light, it will be reflected by the mirrors at (2,2),(2,1),(1,1),(1,2)(2,2), (2,1), (1,1), (1,2)(2,2),(2,1),(1,1),(1,2) repeatedly and stay in the mirror maze.
· For the second light, it will be reflected by (2,3)(2,3)(2,3) and go back to (2,2)(2,2)(2,2), then reflected by (2,2)(2,2)(2,2), go below, and get away from the mirror maze.

简单翻译,就是一个镜子迷宫,一束光在选定点射出,模拟+搜索,先找链,再找环,这题能补出来纯靠队友。

下面是代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//#define endl "\n"
#define fir first
#define sec second
const int N=2005,INF=0x3f3f3f3f3f3f3f3f;
int dir[9][2]= {0,0,-1,0,1,0,0,-1,0,1,1,1,1,-1,-1,1,-1,-1};
int n,m,t;
char cc[1005][1005];
int ans[1005][1005][5],vis[1005][1005][5];
int zhuanxiang(int w,char c) {
    if(w==1) {
        if(c=='-')return 2;
        else if(c=='\\')return 3;
        else if(c=='/')return 4;
        else return 1;
    } else if(w==2) {
        if(c=='-')return 1;
        else if(c=='\\')return 4;
        else if(c=='/')return 3;
        else return 2;
    } else if(w==3) {
        if(c=='|')return 4;
        else if(c=='\\')return 1;
        else if(c=='/')return 2;
        else return 3;
    } else {
        if(c=='|')return 3;
        else if(c=='\\')return 2;
        else if(c=='/')return 1;
        else return 4;
    }
}
void dfs(int x,int y,int w,int len) {
    int tx=x+dir[w][0],ty=y+dir[w][1];
    if(tx<1||ty<1||tx>n||ty>m)return ;
    if(w==zhuanxiang(w,cc[tx][ty]))dfs(tx,ty,w,len);
    else if(vis[tx][ty][0])dfs(tx,ty,zhuanxiang(w,cc[tx][ty]),len);
    else if(!vis[tx][ty][0]) {
        vis[tx][ty][0]=1;
        dfs(tx,ty,zhuanxiang(w,cc[tx][ty]),len+1);
        vis[tx][ty][0]=0;
    }
    if(w==1)ans[tx][ty][2]=len;
    else if(w==2)ans[tx][ty][1]=len;
    else if(w==3)ans[tx][ty][4]=len;
    else if(w==4)ans[tx][ty][3]=len;
}
int DFS(int x,int y,int w,int len) {
    if(vis[x][y][w])return ans[x][y][w]=len;
    vis[x][y][w]=1;
    int tx=x+dir[w][0],ty=y+dir[w][1];
    if(w==zhuanxiang(w,cc[tx][ty])) return ans[x][y][w]=DFS(tx,ty,w,len);
    else if(vis[tx][ty][0])return ans[x][y][w]=DFS(tx,ty,zhuanxiang(w,cc[tx][ty]),len);
    else {
        vis[tx][ty][0]=1;
        ans[x][y][w]=DFS(tx,ty,zhuanxiang(w,cc[tx][ty]),len+1);
        vis[tx][ty][0]=0;
        return ans[x][y][w];
    }
}
signed main() {
    IOS
    cin>>n>>m;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            cin>>cc[i][j];
            for(int k=1; k<=4; k++) {
                ans[i][j][k]=-1;
            }
        }
    }
    for(int i=1; i<=m; i++) {
        vis[0][i][0]=1;
        dfs(0,i,2,0);
        vis[0][i][0]=0;
        vis[n+1][i][0]=1;
        dfs(n+1,i,1,0);
        vis[n+1][i][0]=0;
    }
    for(int i=1; i<=n; i++) {
        vis[i][0][0]=1;
        dfs(i,0,4,0);
        vis[i][0][0]=0;
        vis[i][m+1][0]=1;
        dfs(i,m+1,3,0);
        vis[i][m+1][0]=0;
    }
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            for(int k=1; k<=4; k++) {
                if(ans[i][j][k]==-1) ans[i][j][k]=DFS(i,j,k,0);
            }
        }
    }
    cin>>t;
    while(t--) {
        int x,y;
        string s;
        cin>>x>>y>>s;
        int w;
        if(s=="above")    w=1;
        else if(s=="below")    w=2;
        else if(s=="left")    w=3;
        else if(s=="right")    w=4;
        cout<<ans[x][y][w]<<endl;
    }
    return 0;
}

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值