浑水摸鱼
题目传送门
没有想到这个题目竟然是远古abc的f题
赛中错误思路
首先他有k步的说法,所以我就记录一下上一步是什么方向走过来的吗。然后,就可以计算了。
但是问题是什么?
就是说每一步你是不能直接更改(我不确定可不可以取min,没试过),因为你bfs你要保证每一步是单调的,但是这样就是不单调了对吧。
那么正解是什么?
我们有一些点是重复计算了的。虽然如果这个点不合法是不可以走的,但是如果这一个方向上有一个点他已经走过了,而且步数比现在少,那也就是后面的点就不用走了。
为什么?
因为后面的点总归可以从这个点走过去,总归不会比现在这个点劣。
代码如下
#include<bits/stdc++.h>
using namespace std;
const int d[4][2]={
{-1,0},{1,0},{0,-1},{0,1}
};
int n,m,k;
int xa,ya,xb,yb;
int main(){
cin.tie(0)->sync_with_stdio(0);
freopen("hun.in","r",stdin);
freopen("hun.out","w",stdout);
cin>>n>>m>>k;
cin>>xa>>ya>>xb>>yb;
vector<string> s(n);
vector<vector<bool>> b(n+1,vector<bool>(m+1,0));
vector<vector<int>> dist(n+1,vector<int>(m+1,1<<30));
queue<pair<int,int>> q;
for(int i=0;i<n;i++) cin>>s[i];
xa--,ya--,xb--,yb--;
q.push({xa,ya});
b[xa][ya]=1;
dist[xa][ya]=0;
while(q.size()){
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<4;i++){
for(int j=1;j<=k;j++){
int xx=x+d[i][0]*j;
int yy=y+d[i][1]*j;
if(xx<0||yy<0||xx>=n||yy>=m||s[xx][yy]=='@') break;
if(dist[xx][yy]<=dist[x][y]) break;
if(b[xx][yy]) continue;
q.push({xx,yy});
b[xx][yy]=1;
dist[xx][yy]=dist[x][y]+1;
}
}
}
if(dist[xb][yb]!=1<<30) cout<<dist[xb][yb]<<endl;
else cout<<-1<<endl;
}

浙公网安备 33010602011771号