[BalticOI 2011 Day1]Switch the Lamp On

[BalticOI 2011 Day1]Switch the Lamp On

题面翻译

题目描述

Casper 正在设计电路。有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。有 N × M N\times M N×M 个这样的元件,你想将其排列成 N N N 行,每行 M M M 个。 电源连接到板的左上角。灯连接到板的右下角。只有在电源和灯之间有一条电线连接的情况下,灯才会亮着。为了打开灯,任何数量的电路元件都可以转动 90°(两个方向)。

[BalticOI 2011 Day1]Switch the Lamp On_第1张图片

[BalticOI 2011 Day1]Switch the Lamp On_第2张图片

在上面的图片中,灯是关着的。如果右边的第二列的任何一个电路元件被旋转 90°,电源和灯都会连接,灯被打开。现在请你编写一个程序,求出最小需要多少旋转多少电路元件。

输入输出格式

输入格式

输入的第一行包含两个整数 N N N M M M,表示盘子的尺寸。 在以下 N N N 行中,每一行有 M M M 个符号 \/,表示连接对应电路元件对角线的导线的方向。

输出格式:

如果可以打开灯,那么输出只包含一个整数,表示最少转动电路元件的数量。

如果不可能打开灯,输出 NO SOLUTION

题目描述

Casper is designing an electronic circuit on a N × M N \times M N×M rectangular grid plate. There are N × M N \times M N×M square tiles that are aligned to the grid on the plate. Two (out of four) opposite corners of each tile are connected by a wire.

A power source is connected to the top left corner of the plate. A lamp is connected to the bottom right corner of the plate. The lamp is on only if there is a path of wires connecting power source to lamp. In order to switch the lamp on, any number of tiles can be turned by 90° (in both directions).

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zOshJedz-1686230911462)(null)]

In the picture above the lamp is off. If any one of the tiles in the second column from the right is turned by 90° , power source and lamp get connected, and the lamp is on.

Write a program to find out the minimal number of tiles that have to be turned by 90° to switch the lamp on.

输入格式

The first line of input contains two integer numbers N N N and M M M, the dimensions of the plate. In each of the following N N N lines there are M M M symbols – either \ or / – which indicate the direction of the wire connecting the opposite vertices of the corresponding tile.

输出格式

There must be exactly one line of output. If it is possible to switch the lamp on, this line must contain only one integer number: the minimal number of tiles that have to be turned to switch on the lamp. If it is not possible, output the string: NO SOLUTION

样例 #1

样例输入 #1

3 5
\\/\\
\\///
/\\\\

样例输出 #1

1

提示

对于 40 % 40\% 40% 的数据, 1 ≤ N ≤ 4 1 \le N \le 4 1N4 1 ≤ M ≤ 5 1 \le M \le 5 1M5

对于所有数据, 1 ≤ N , M ≤ 500 1 \le N,M \le 500 1N,M500

代码

#include
using namespace std;
struct point{
	int x,y;
	point(int x=0,int y=0): x(x),y(y){}
};
int n,m;
const int ix[]={0,-1,-1,0};
const int iy[]={0,0,-1,-1};
const int dx[]={1,-1,-1,1};
const int dy[]={1,1,-1,-1};
const char a[]="\\/\\/";
deque<point> qu;
char G[510][510];int dis[510][510];
void bfs(){
	memset(dis,0x3f3f3f,sizeof(dis));
	point tmp(0,0);
	qu.push_back(tmp);
	dis[0][0]=0;
	while(!qu.empty()){
		point now=qu.front();
		qu.pop_front();
		for (int i=0;i<4;i++){
			point future(now.x+dx[i],now.y+dy[i]);
			int xx=now.x+ix[i],yy=now.y+iy[i];
			if (future.x>=0 and future.x<=n and future.y>=0 and future.y<=m){
				int tt=dis[now.x][now.y];
				int t=tt;
				if (a[i]!=G[xx][yy]) t++;
				if (t<dis[future.x][future.y]){
					if (t!=tt) qu.push_back(future);
					else qu.push_front(future);
					dis[future.x][future.y]=t;
				}
			}
		} 
	}
	return;
}
int main(){
	cin>>n>>m;
	for (int i=0;i<n;i++) scanf("%s",G[i]);
	bfs();
	if ((n+m)%2) cout<<"NO SOLUTION";
	else cout<<dis[n][m];
	return 0;
}

分析

大致思路:求解迷宫最短路径,使用算法BFS,去处理带“/”和“\”障碍物的迷宫。

具体思路:定义一个结构体point表示坐标,在bfs()函数中,通过当前点周围4个方向的偏移量数组,生成下一个可能的点,然后根据迷宫当中的障碍物与之前的点之间是否为 “/” 或 “\”,选择不同的策略来更新该点到起点的最小距离,并将新的可行点添加到双端队列中以便后续处理。最后,输出从起点到终点的最短距离。

辅助数组

定义了四个数组和一个字符串,分别为 ix、iy、dx、dy 和 a。

求格子在G中的下标数组:ix 和 iy 。

移动数组:
dx 和 dy ,分别代表相邻格子在斜向上的偏移量,对应着四个方向,例如 dx[0] 和 dy[0] 分别代表向右下方的偏移量,在横坐标和纵坐标上都加一。

最后,字符串 a 包含四个字符,即 ‘\’, ‘/’, ‘\’, ‘/’,表示相邻两个点之间的连接方式可能为反斜杠、正斜杠、反斜杠或正斜杠。

bfs

此搜索有先后顺序,权小的放队头,大的放队尾,需要双端队列deque.

你可能感兴趣的:(算法)