Mirror Maze(DFS)

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

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.

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

const int N=2e5+5;
const int C=2e3+5;
const int inf=0x3f3f3f3f3f3f3f3f;
 
int n,m,q,u,v;
string dir;
char mi[C][C];
int vis[C][C][5],ans[C][C][5];
set<pair<int,int>>mp;//记录反射过的镜子坐标

void dfs(int i,int j,int dir) { //射到(i,j)的方向为dir的光线
	if(i<1 || j<1 || i>n || j>m) return;//光线出去了
	if(vis[i][j][dir] == 2) return;//形成回路

	vis[i][j][dir]++;
	int now;//反射后的方向
	if(mi[i][j] == '|') {
		if(dir == 1) now=1;
		if(dir == 2) now=2;
		if(dir == 3) now=4;
		if(dir == 4) now=3;
	}

	if(mi[i][j] == '\\') {
		if(dir == 1) now=3;
		if(dir == 2) now=4;
		if(dir == 3) now=1;
		if(dir == 4) now=2;
	}

	if(mi[i][j] == '/') {
		if(dir == 1) now=4;
		if(dir == 2) now=3;
		if(dir == 3) now=2;
		if(dir == 4) now=1;
	}

	if(mi[i][j] == '-') {
		if(dir == 1) now=2;
		if(dir == 2) now=1;
		if(dir == 3) now=3;
		if(dir == 4) now=4;
	}

	if(now == 1) dfs(i-1,j,now);
	if(now == 2) dfs(i+1,j,now);
	if(now == 3) dfs(i,j-1,now);
	if(now == 4) dfs(i,j+1,now);
	
	if(now!=dir) mp.insert({i,j});
	vis[i][j][dir]=0;
	ans[i][j][dir]=mp.size();
}

signed main() {
	ios
	cin >> n >> m;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++) cin >> mi[i][j];

	for(int i=1; i<=n; i++) {
		mp.clear();
		dfs(i,1,4);//在(i,1)处>
		mp.clear();
		dfs(i,m,3);//在(i,m)处<
	}

	for(int j=1; j<=m; j++) {
		mp.clear();
		dfs(1,j,2);//在(1,j)处v
		mp.clear();
		dfs(n,j,1);//在(n,j)处^
	}

	for(int i=1; i<=n; i++) { //计算剩余的,即环形光路
		for(int j=1; j<=m; j++) {
			if(!ans[i][j][1]) {
				mp.clear();
				dfs(i,j,1);
			}
			if(!ans[i][j][2]) {
				mp.clear();
				dfs(i,j,2);
			}
			if(!ans[i][j][3]) {
				mp.clear();
				dfs(i,j,3);
			}
			if(!ans[i][j][4]) {
				mp.clear();
				dfs(i,j,4);
			}
		}
	}

	cin >> q;
	while(q--) {
		cin >> u >> v >> dir;
		if(dir == "above") cout  <<  ans[u-1][v][1] << endl;
		if(dir == "below") cout << ans[u+1][v][2] << endl;
		if(dir == "left") cout << ans[u][v-1][3] << endl;
		if(dir == "right") cout << ans[u][v+1][4] << endl;
	}
	return 0;
}

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是对DFS、BFS和UCS的介绍: DFS(深度优先搜索):总是扩展最深层的节点,使用的是LIFO队列,即使用的是stack栈。DFS在生成节点时做的goal test,因此在搜索树中,DFS总是沿着最深的路径搜索,直到找到目标状态或者无法继续搜索为止。DFS的优点是空间复杂度低,但是可能会陷入局部最优解。 BFS(广度优先搜索):总是扩展最浅层的节点,使用的是FIFO队列,即使用的是queue队列。BFS在扩展节点时做的goal test,因此在搜索树中,BFS总是沿着最浅的路径搜索,直到找到目标状态或者无法继续搜索为止。BFS的优点是可以找到最优解,但是空间复杂度较高。 UCS(最佳优先搜索):总是扩展当前代价最小的节点,使用的是priority queue优先队列。UCS在扩展节点时做的goal test,因此在搜索树中,UCS总是沿着代价最小的路径搜索,直到找到目标状态或者无法继续搜索为止。UCS的优点是可以找到最优解,且可以在frontier集中记录所有合适的解,但是空间复杂度较高。 以下是对DFS、BFS和UCS的演示: 假设我们要在一个迷宫中找到从起点到终点的最短路径,其中1表示墙,0表示可以通过的路。迷宫如下所示: ``` 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 ``` 我们可以使用DFS、BFS和UCS来寻找最短路径。其中DFS使用stack栈,BFS使用queue队列,UCS使用priority queue优先队列。具体实现可以参考以下代码: ```python # DFS def dfs(maze, start, end): stack = [(start, [start])] visited = set() while stack: node, path = stack.pop() if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): stack.append((neighbor, path + [neighbor])) return None # BFS def bfs(maze, start, end): queue = [(start, [start])] visited = set() while queue: node, path = queue.pop(0) if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): queue.append((neighbor, path + [neighbor])) return None # UCS def ucs(maze, start, end): queue = [(0, start, [start])] visited = set() while queue: cost, node, path = heapq.heappop(queue) if node == end: return path if node not in visited: visited.add(node) for neighbor in get_neighbors(maze, node): new_cost = cost + 1 heapq.heappush(queue, (new_cost, neighbor, path + [neighbor])) return None # 获取邻居节点 def get_neighbors(maze, node): neighbors = [] row, col = node if row > 0 and maze[row-1][col] == 0: neighbors.append((row-1, col)) if row < len(maze)-1 and maze[row+1][col] == 0: neighbors.append((row+1, col)) if col > 0 and maze[row][col-1] == 0: neighbors.append((row, col-1)) if col < len(maze[0])-1 and maze[row][col+1] == 0: neighbors.append((row, col+1)) return neighbors ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值