CF877D

Olya and Energy Drinks

题面翻译

题目描述

有一NxM的迷宫,'#'是墙,‘.’是路,一秒钟可以向四个方向中的一个移动1~k步,求从起点到终点的最短时间。

输入格式:

第一行n、m、k,下面是NxM的迷宫,最后是起点到终点的坐标。

输出格式:

输出最短时间。如果不能离开迷宫,输出-1。

样例 #1

样例输入 #1

3 4 4
....
###.
....
1 1 3 1

样例输出 #1

3

样例 #2

样例输入 #2

3 4 1
....
###.
....
1 1 3 1

样例输出 #2

8

样例 #3

样例输入 #3

2 2 1
.#
#.
1 1 2 2

样例输出 #3

-1
有几个点:
不走回头路
当kk枚举时有越界的直接break
在扩展子节点时也判断到没到终点
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m,k,sx,sy,tx,ty;
bool vis[1005][1005];
char a[1005][1005];
int dx[4]= {1,0,-1,0};
int dy[4]= {0,1,0,-1};
struct did {
	int x,y,c,fx;
};
queue<did>q;
void bfs() {
	vis[sx][sy]=1;
	did z;
	z.x=sx,z.y=sy,z.c=0;
	z.fx=-12;
	q.push(z);
	while(!q.empty()) {
		did z=q.front();
		q.pop();
		int x=z.x,y=z.y;
		if(x==tx&&y==ty) {
			cout<<z.c<<"\n";
			exit(0);
		}
		for(int i=0; i<4; i++) {
			for(int kk=1; kk<=k; kk++) {
				int nx=x+dx[i]*kk,ny=y+dy[i]*kk;
				if(nx>n||ny>m||nx<1||ny<1)break;
				if(a[nx][ny]=='#')break;
				if(vis[nx][ny])continue;
				if(abs(z.fx-(i+1))==2)continue;
				vis[nx][ny]=1;
				did t;
				t.x=nx,t.y=ny,t.c=z.c+1;
				t.fx=i+1;
				if(nx==tx&&ny==ty)
				{
					cout<<t.c<<"\n";
					exit(0);
				}
				q.push(t);
			}
		}
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin>>n>>m>>k;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			cin>>a[i][j];
	cin>>sx>>sy>>tx>>ty;
	if(sx==tx&&sy==ty) {
		cout<<0<<"\n";
		return 0;
	}
	bfs();
	cout<<-1<<"\n";
	return 0;
}
posted @ 2023-01-26 10:50  PKU_IMCOMING  阅读(16)  评论(0)    收藏  举报