NC51025. 电路维修
描述
Ha'nyu是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女Rika,从而被收留在地球上。Rika的家里有一辆飞行车。有一天飞行车的电路板突然出现了故障,导致无法启动。
电路板的整体结构是一个R行C列的网格(R,C≤500),如右图所示。每个格点都是电线的接点,每个格子都包含一个电子元件。电子元件的主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆。在旋转之后,它就可以连接另一条对角线的两个接点。电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。
Ha'nyu发现因为某些元件的方向不小心发生了改变,电路板可能处于断路的状态。她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。不过,电路的规模实在是太大了,Ha'nyu并不擅长编程,希望你能够帮她解决这个问题。
输入描述
输入文件包含多组测试数据。第一行包含一个整数T 表示测试数据的数目。
对于每组测试数据,第一行包含正整数R 和C,表示电路板的行数和列数。
之后R 行,每行C 个字符,字符是"/"和"\"中的一个,表示标准件的方向。
输出描述
对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
如果无论怎样都不能使得电源和发动机之间连通,输出NO SOLUTION。
示例1
输入:
1 3 5 \\/\\ \\/// /\\\\
输出:
1
说明:
样例的输入对应于题目描述中的情况。
只需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。
C++11(clang++ 3.9) 解法, 执行用时: 60ms, 内存消耗: 3224K, 提交时间: 2020-08-25 11:30:55
#include<bits/stdc++.h> using namespace std; char s[550][550]; int r,c; struct node{ int i,j,step; }Node; deque<node> dq; bool vis[550][550]; void judge(int x,int y,int sx,int sy,int sp,char ch){ if(x>=0&&y>=0&&x<=r&&y<=c&&vis[x][y]==false){ if(s[sx][sy]==ch) dq.push_front((node){x,y,sp}); else dq.push_back((node){x,y,sp+1}); } } int bfs(){ while(dq.size()) dq.pop_back(); Node.i=Node.j=Node.step=0; dq.push_front(Node); while(dq.size()){ node now=dq.front(); dq.pop_front(); if(vis[now.i][now.j]) continue; vis[now.i][now.j]=true; if(now.i==r&&now.j==c) return now.step; int x=now.i,y=now.j; judge(x+1,y+1,x+1,y+1,now.step,'\\'); judge(x-1,y-1,x,y,now.step,'\\'); judge(x+1,y-1,x+1,y,now.step,'/'); judge(x-1,y+1,x,y+1,now.step,'/'); } } int main(){ int t; cin>>t; while(t--){ memset(vis,false,sizeof(vis)); cin>>r>>c; for(int i=1;i<=r;i++){ for(int j=1;j<=c;j++){ cin>>s[i][j]; } } if((r+c)&1) cout<<"NO SOLUTION"<<endl; else cout<<bfs()<<endl; } return 0; }