Loj 10028 Knight Moves

从题意可以看出这是一道BFS 题,他让从起点搜到终点,我们可以从起点和终点两个方向一块向中间搜索,最后把两个路径数相加即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int grp,n;
struct sw{
	int x,y;
}q[2][100000];
int ans,l[2],r[2];
int dis[3][301][301],v[2][304][304];
int dx[8]={1,2,2,1,-1,-2,-2,-1};
int dy[8]={2,1,-1,-2,-2,-1,1,2};
int expand(int k) {
	int t,i,j,x,y,d,tx,ty;
	x=q[k][l[k]].x;
	y=q[k][l[k]].y;
	d=dis[k][x][y];
	for(int i=0;i<8;i++) {
		tx=x+dx[i];
		ty=y+dy[i];
		if(tx>=0&&tx<=n&&ty>=0&&ty<=n&&!v[k][tx][ty]) {
			v[k][tx][ty]=1;
			r[k]++;
			q[k][r[k]].x=tx;q[k][r[k]].y=ty;
			dis[k][tx][ty]=d+1;
			if(v[1-k][tx][ty]) {
				ans=dis[k][tx][ty]+dis[1-k][tx][ty];
				return 1;
			}
		}
	}
	return 0;
	
}
void bfs() {
	if(q[0][1].x==q[1][1].x&&q[0][1].y==q[1][1].y) {
		ans=0;return ;
	}
	v[0][q[0][1].x][q[0][1].y]=1;
	v[1][q[1][1].x][q[1][1].y]=1;
	l[0]=r[0]=1;l[1]=r[1]=1;
	while(l[0]<=r[0]&&l[1]<=r[1]) {
		if(r[0]-l[0]<r[1]-l[1]) {
			if(expand(0)) return ;
			l[0]++;
		}
		else{
			if(expand(1)) return ;
			l[1]++;
		}
	}
}
int main() {
	scanf("%d",&grp);
	for(int i=1;i<=grp;i++) {
		memset(v,0,sizeof(v));
		memset(q,0,sizeof(q));
		memset(dis,0,sizeof(dis));
		scanf("%d",&n);
		n--;
		scanf("%d%d%d%d",&q[0][1].x,&q[0][1].y,&q[1][1].x,&q[1][1].y);
		bfs();
		cout<<ans<<endl;
	}
	return 0;
}

!!错误:中间判断起点和重点是否相等时直接用了break,导致直接跳出循环。

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/zailingzhe/article/details/88649517
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞