题目链接:http://172.18.70.217/problem/19
题目大意:通过改变格子中正反斜杠方向找到一条从起点到终点的路径,并使改变斜杠方向的次数最少。
通过分析我们很容易发现,我们可以将格子的四个角当成4个点,而斜杠本身当成一条边。那么对于一个点来说,与之相邻的点就有两种:
第一种:能够不改变斜杠方向就能到达的点。
第二种:通过改变斜杠方向后就能到达的点。
那么我们可以通过求出从起点到(x,y)这个点需要改变斜杠方向的次数,从而逐步求出其周围点的情况,最后求出到(R+1,C+1)这个点需要改变的最小次数(因为是以顶点作为新的点,所以长和宽都变大了)。那么我们很容易就可以想到通过BFS得到答案。但是一些需要注意的地方:
1.开两个队列,一个是正常的遍历队列s,另一个是将之前遍历过的点存储下来进行其它的遍历New。
2.先将从队列s的队首元素出发,不需要改变斜杠的方向就可到达的点,然后将这所有遍历过的点都压入另一个队列中。
3.当队列s为空时,开始遍历队列New中的点,获得从这一些点出发只需改变一次斜杠就能到达的点,直到队列New为空为止。
达成以上三点就可以避免出现,本来可以以更少的次数得到的答案,在更大次数背景下先被访问的问题。
下面附上AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
typedef int ll;
char mp[1010][1010];
bool vis[1010][1010];
ll R,C,flag=0;
ll cx[4]={-1,-1,1,1};
ll cy[4]={-1,1,-1,1};
struct node
{
ll x;
ll y;
ll times;
};
void bfs()
{
memset(vis,false,sizeof(vis));
queue<node> s;
queue<node> New;
node fir;
fir.x=1;fir.y=1;fir.times=0;
s.push(fir);
vis[1][1]=true;
ll ans=0;
while(!s.empty())
{
node u=s.front();
s.pop();
if(u.x==R+1 && u.y==C+1)
{
printf("%d\n",u.times);
flag=1;
return;
}
for(ll i=0;i<4;i++)
{
node v=u;
v.x=u.x+cx[i];
v.y=u.y+cy[i];
if(!vis[v.x][v.y] && v.x>=1 && v.x<=R+1 && v.y>=1 && v.y<=C+1)
{
if(i==0 && mp[u.x-1][u.y-1]=='\\')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==1 && mp[u.x-1][u.y]=='/')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==2 && mp[u.x][u.y-1]=='/')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==3 && mp[u.x][u.y]=='\\')
{
vis[v.x][v.y]=true;
s.push(v);
}
}
}
New.push(u);
if(!s.empty())
continue;
while(!New.empty())
{
u=New.front();
New.pop();
for(ll i=0;i<4;i++)
{
node v=u;
v.x=u.x+cx[i];
v.y=u.y+cy[i];
v.times++;
if(!vis[v.x][v.y] && v.x>=1 && v.x<=R+1 && v.y>=1 && v.y<=C+1)
{
if(i==0 && mp[u.x-1][u.y-1]=='/')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==1 && mp[u.x-1][u.y]=='\\')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==2 && mp[u.x][u.y-1]=='\\')
{
vis[v.x][v.y]=true;
s.push(v);
}
if(i==3 && mp[u.x][u.y]=='/')
{
vis[v.x][v.y]=true;
s.push(v);
}
}
}
}
}
}
int main()
{
ll T;
cin>>T;
while(T--)
{
cin>>R>>C;
for(ll i=1;i<=R;i++)
for(ll j=1;j<=C;j++)
cin>>mp[i][j];
flag=0;
bfs();
if(flag==0)
printf("NO SOLUTION\n");
}
return 0;
}