#MNS148. 迷宫
【题目描述】
给你一个 行
列的包含
,
的矩阵,
表示空地,
表示障碍。起点为左上角
位置,终点为右下角
位置,每次只能向右走、向下走、向左走、向右走:假如当前在位置
,你只能走到
,
,
,
位置。
每个位置每个单位时间会变换状态,例如 在第
个单位时间是空地,则在第
个单位时间是障碍。
在第
个单位时间是障碍,则在第
个单位时间是空地。
保证起点的初始状态是空地。保证起点出发可以到达终点。
问起点到终点的最短时间。
【输入格式】
从
maze.in
中读入数据。
第一行一个正整数 。
接下来 行,每行一个长度为
的整数序列,描述这个字符矩阵。
【输出格式】
输出到
maze.out
中。
一行一个数,表示答案。
【输入样例 1】
3
0 0 0
1 0 1
0 1 0
【输出样例 1】
4
【输入样例 2】
3
0 0 0
1 0 0
0 1 0
【输出样例 2】
4
【数据范围及约定】
- 对于测试点
:
- 对于测试点
:
- 对于测试点
:
【题解】
考虑。
表示从起点出发到达位置
的最短时间。
考虑当前位置的最短时间是
,下一步是
,
,
,
之一。
需要满足在第个单位时间时,下一步的位置必须是空地。
考虑空地的判定条件,因为每个单位时间是一个循环,所以满足
是偶数时,位置
是空地。
则即为答案。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int a[1005][1005];
int dis[1005][1005];
int main()
{
//freopen("maze.in","r",stdin);
//freopen("maze.out","w",stdout);
std::ios::sync_with_stdio(false),cin.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a[i][j];
memset(dis,0x3f,sizeof(dis));
queue<array<int,2>>q;
q.push({0,0});
dis[0][0]=0;
vector<array<int,2>>d={{0 , 1},{0,-1},{-1,0},{1,0}};
auto ok=[&](int x,int y,int t){
if(x<0 || x>=n || y<0 || y>=n)return false;
if((a[x][y]+t) & 1)return false;
if(dis[x][y]!=inf)return false;
return true;
};
while(!q.empty()){
auto[x,y]=q.front();
q.pop() ;
int t=dis[x][y];
for(int i=0;i<4;i++){
int nx=x+d[i][0];
int ny=y+d[i][1];
if(ok(nx,ny,t+1)){
dis[nx][ny]=min(dis[nx][ny],t+1);
q.push({nx,ny});
}
}
}
if(dis[n-1][n-1]==inf)cout<<-1<<endl;
else cout<<dis[n-1][n-1]<<endl;
return 0;
}