题目地址:https://www.acwing.com/problem/content/177/
题目描述:
达达是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女翰翰,从而被收留在地球上。
翰翰的家里有一辆飞行车。
有一天飞行车的电路板突然出现了故障,导致无法启动。
电路板的整体结构是一个R行C列的网格(R,C≤500),如下图所示。
每个格点都是电线的接点,每个格子都包含一个电子元件。
电子元件的主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆。
在旋转之后,它就可以连接另一条对角线的两个接点。
电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。
达达发现因为某些元件的方向不小心发生了改变,电路板可能处于断路的状态。
她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。
不过,电路的规模实在是太大了,达达并不擅长编程,希望你能够帮她解决这个问题。
注意:只能走斜向的线段,水平和竖直线段不能走。
输入格式
输入文件包含多组测试数据。
第一行包含一个整数T,表示测试数据的数目。
对于每组测试数据,第一行包含正整数R和C,表示电路板的行数和列数。
之后R行,每行C个字符,字符是"/"
和""
中的一个,表示标准件的方向。
输出格式
对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
如果无论怎样都不能使得电源和发动机之间连通,输出NO SOLUTION。
数据范围
1≤R,C≤500
1≤T≤5
题解:假设左上角的起点是(0,0),那么只有位置i+j是偶数,才会到达,因为当前在(0,0)那么每一步移动,都是沿着斜线,那么横纵坐标都会变化1,所以变化后的和还是偶数。所以,根绝这个我们便可以首先排除一些样例肯定是不会到达的,而且这个特性在后面用最短路来抽象的时候会用到。那么接下来就是抽象整个问题了,题目的问题是求最少移动多少线可以到达目的地。那么我们便可以本来有线的边看作权值是0,没有线需要移动的是1.而且这里面因为之前说过一些点不会到达,所以可以放心的将线移动。这道题可以利用双端队列+搜索来进行。
双端队列适用于:只包含0和1的最短路问题。当前点扩展出来的边的权值为0的则将边的另一个端点插入队首,为1则插入队尾。其余剩下的就和一般的bfs一样 。
AC代码:
#include<iostream> #include<cstdio> #include<deque> #include<cstring> using namespace std; const int N=510; typedef pair<int ,int > PII; char gr[N][N]; int dis[N][N],r,c; int bfs(){ deque<PII>de; memset(dis,0x3f,sizeof dis); dis[0][0]=0; de.push_front(make_pair(0,0)); int rx[4]={-1,-1,1,1},ry[4]={-1,1,1,-1};//这个是对结点进行上下左右移动的,从左上角开始顺时针的存储 int ix[4]={-1,-1,0,0},iy[4]={-1,0,0,-1};//这个是对当前结点按照上面方法移动之后,所需要对应的边所在的数组位置的移动方法 char cs[]="\/\/"; while(!de.empty()){ PII now=de.front();de.pop_front(); for(int i=0;i<4;i++){ int ra=now.first+rx[i],rb=now.second+ry[i]; if(ra<0||ra>r||rb<0||rb>c) continue; int ia=now.first+ix[i],ib=now.second+iy[i]; if(dis[ra][rb]>dis[now.first][now.second]+(gr[ia][ib]!=cs[i])){ dis[ra][rb]=dis[now.first][now.second]+(gr[ia][ib]!=cs[i]); if(ra==r&&rb==c) return dis[ra][rb]; if(gr[ia][ib]!=cs[i]) de.push_back(make_pair(ra,rb)); else de.push_front(make_pair(ra,rb)); } } } } int main(){ int t;cin>>t; while(t--){ cin>>r>>c; for(int i=0;i<r;i++) for(int j=0;j<c;j++) cin>>gr[i][j]; if(r+c & 1) { cout<<"NO SOLUTION "; continue; } printf("%d ",bfs()); } return 0; }
2020/9/7 19:59