dyc2022
2024-11-20 18:18:07
绝世好题!
题意:给一个
我们可以先思考一个
我们可以从起点开始 BFS,走到一个点可以:
我们发现瓶颈在于传送到
我们可以画一个图,看一下从一个格子传送一次最远能够走到哪里。最极端的情况就是我当前所在的格子和我要传送到的格子正好在这个正方形对角线的两端。因此,我们容易发现:我们能够传送到的点,恰好就是从当前格子走
想到这里,正解也就呼之欲出了。我们依然可以 01BFS,在每个节点存当前坐标,当前代价和还能走多少步八联通。复杂度为
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define N 6000006
using namespace std;
int n,m,k,sx,sy,ex,ey;
vector<int> mp[N],vis[N];
struct Node{int x,y,dis,lef;};
deque<Node> dq;
char ch[N];
int dx[]={0,0,1,-1,1,1,-1,-1};
int dy[]={-1,1,0,0,1,-1,1,-1};
main()
{
scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&sx,&sy,&ex,&ey);
for(int i=1;i<=n;i++)
{
mp[i].push_back(0),vis[i].push_back(0);
scanf("%s",ch+1);
for(int j=1;j<=m;j++)mp[i].push_back(ch[j]=='#'),vis[i].push_back(0);
}
dq.push_back({sx,sy,0,0});
while(dq.size())
{
Node now=dq.front();dq.pop_front();
if(vis[now.x][now.y])continue;
if(now.x==ex&&now.y==ey)return printf("%lld\n",now.dis),0;
vis[now.x][now.y]=1;
if(now.lef)
{
for(int i=0;i<8;i++)
{
int tx=now.x+dx[i],ty=now.y+dy[i];
if(tx>0&&ty>0&&tx<=n&&ty<=m&&!vis[tx][ty])
dq.push_back({tx,ty,now.dis,now.lef-1});
}
}
else
{
for(int i=0;i<4;i++)
{
int tx=now.x+dx[i],ty=now.y+dy[i];
if(tx>0&&ty>0&&tx<=n&&ty<=m&&!vis[tx][ty])
{
if(mp[tx][ty])dq.push_back({tx,ty,now.dis+1,k-1});
else dq.push_front({tx,ty,now.dis,0});
}
}
}
}
return 0;
}