题解:P13096 [FJCPC 2025] 难以控制的滑板火箭
给定一张图,
求从
第一眼,肯定和 bfs 求最短路有关。假设最短路长度是
第二眼,时间最短肯定开始阶段都进行
所以答案就是
不过这个肯定是答案的下界,我们考虑一下什么情况下可以达到这个下界。
首先,如果
设
怎么消耗掉这些多余的步骤呢?一个最简单的方法就是在终点和终点前一点反复横跳,这样一轮操作会消耗掉
当然,如果
如果
接下来只剩一种情况了,就是
- 通过分层图的方法求出奇偶最短路的长度。
- 如果
l \not = r ,答案就是下界。 - 如果
l = r 。判断l 的奇偶性。如果l 为偶数,考虑偶数最短路至少加几个2 可以变成r 的倍数。其实稍微思考可以发现,也就是下界。如果l 是奇数,则分别判断奇最短路和偶最短路。
注意到
考虑到
const int N=1010;
const int inf=0x3f3f3f3f;
int dis[N][N][2];
bool vis[N][N][2];
int n,m,a[N][N],l,r,ans;
const int dx[]={0,0,-1,-1,-1,1,1,1};
const int dy[]={1,-1,0,1,-1,0,-1,1};
queue<int> q;
void bfs(int s,int t){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
dis[i][j][0]=dis[i][j][1]=inf;
vis[i][j][0]=vis[i][j][1]=false;
}
while (!q.empty()) q.pop();
q.push(s);q.push(t);q.push(0);
dis[s][t][0]=0;
vis[s][t][0]=true;
while (!q.empty()){
int u=q.front();q.pop();
int v=q.front();q.pop();
int d=q.front();q.pop();
for(int i=0;i<8;i++){
int x=u+dx[i],y=v+dy[i];
if (x<1||x>n||y<1||y>m) continue;
if (!vis[x][y][!d]&&a[x][y]){
vis[x][y][!d]=true;
dis[x][y][!d]=dis[u][v][d]+1;
q.push(x);
q.push(y);
q.push(!d);
}
}
}
}//分层图最短路
int OZDY(){
scanf("%d%d",&n,&m);
scanf("%d%d",&l,&r);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&a[i][j]);
bfs(1,1);
int u=dis[n][m][0],v=dis[n][m][1];
if (l!=r){
if (u==inf&&v==inf) printf("-1\n");//无解
else printf("%d\n",(min(u,v)+r-1)/r);
}
else{
if (l&1){
if (u==inf&&v==inf) puts("-1");
else{
ans=inf;
if (u!=inf){
int tmp=u/l;
if (u%l==0) ;
else if (u%2==tmp%2) tmp+=2;
else tmp++;
ans=min(ans,tmp);
}//偶最短路
if (v!=inf){
int tmp=v/l;
if (v%l==0) ;
else if (v%2==tmp%2) tmp+=2;
else tmp++;
ans=min(ans,tmp);
}//奇最短路,两种的处理完全对称
printf("%d\n",ans);
}
}
else{
if (u==inf) puts("-1");
else printf("%d\n",(u+r-1)/r);
}//l 为偶数,其倍数也必然是偶数,只需考虑偶最短路
}
return 0;
}