题解 P2226 【[HNOI2001]遥控赛车比赛】

180度转弯,这怕不是强互作用力赛车

题目链接

Solution [HNOI2001]遥控赛车比赛

题目大意:给定一个(n)(m)列的赛场,有些地方有障碍物,给定一个起点和终点,反应速度为(x in[1,10]),两次转弯(方向改变就算转弯,含180度)之间的时间间隔不能低于(x),求(xin [1,10])内的答案

最短路,bfs


分析:

我们尝试用多元组表示当前状态

为了知道我们在哪需要坐标((x,y))

为了知道我们还需要多久可以转弯需要冷却时间(cd)

为了知道我们的方向需要(d)

然后我们用((x,y,cd,d))就可以表示出当前的状态了

转移的话我们(d(u,d,cd))表示当前坐标为(u)(是个二元组),方向为(d),冷却时间为(cd)的最短距离,可以更新:

(d(v,d,cd-1))(d(v,other ;d,x))(x)如上文)

用类似最短路的松弛,跑个(bfs)就好了

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 128;
int dis[4][12][maxn][maxn],inq[4][12][maxn][maxn],mp[maxn][maxn],deltax[] = {-1,0,1,0},deltay[] = {0,1,0,-1},begx,begy,endx,endy,n,m;
struct Node{
	int d,cd,x,y;
};
inline int solve(int mxcd){
	queue<Node> Q;
	memset(dis,0x3f,sizeof(dis));
	dis[0][mxcd][begx][begy] = 0,Q.push(Node{0,mxcd,begx,begy});
	dis[1][mxcd][begx][begy] = 0,Q.push(Node{1,mxcd,begx,begy});
	dis[2][mxcd][begx][begy] = 0,Q.push(Node{2,mxcd,begx,begy});
	dis[3][mxcd][begx][begy] = 0,Q.push(Node{3,mxcd,begx,begy});
	while(!Q.empty()){
		Node now = Q.front();Q.pop();
		inq[now.d][now.cd][now.x][now.y] = 0;
		for(int i = 0;i < 4;i++){
			int nx = now.x + deltax[i],ny = now.y + deltay[i];
			if(nx < 1 || nx > n || ny < 1 || ny > m || !mp[nx][ny])continue;
			if(i == now.d){
				if(dis[now.d][now.cd][now.x][now.y] + 1 < dis[i][now.cd - 1 < 0 ? 0 : now.cd - 1][nx][ny]){
					dis[i][now.cd - 1 < 0 ? 0 : now.cd - 1][nx][ny] = dis[now.d][now.cd][now.x][now.y] + 1;
					if(!inq[i][now.cd - 1 < 0 ? 0 : now.cd - 1][nx][ny])Q.push(Node{i,now.cd - 1 < 0 ? 0 : now.cd - 1,nx,ny}),inq[i][now.cd - 1 < 0 ? 0 : now.cd - 1][nx][ny] = 1;
				}
			}else if(!now.cd){
				if(dis[now.d][now.cd][now.x][now.y] + 1 < dis[i][mxcd - 1][nx][ny]){
					dis[i][mxcd - 1][nx][ny] = dis[now.d][now.cd][now.x][now.y] + 1;
					if(!inq[i][mxcd - 1][nx][ny])Q.push(Node{i,mxcd - 1,nx,ny}),inq[i][mxcd - 1][nx][ny] = 1;
				}
			}
		}
	}
	int res = 0x3f3f3f3f;
	for(int i = 0;i < 4;i++)
		for(int j = 0;j <= mxcd + 1;j++)
			res = min(res,dis[i][j][endx][endy]);
	return res;
}
int main(){
//	freopen("fafa.in","r",stdin);
	scanf("%d %d",&n,&m);
	scanf("%d %d %d %d",&begx,&begy,&endx,&endy);
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= m;j++)
			scanf("%d",&mp[i][j]);
	for(int i = 1;i <= 10;i++){
		int ans = solve(i);
		if(ans < 0x3f3f3f3f)printf("%d %d
",i,ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/colazcy/p/13021636.html