1. 程式人生 > 實用技巧 >題解 UVA439 騎士的移動 Knight Moves

題解 UVA439 騎士的移動 Knight Moves

前言

最近板子題刷多了……

題意

一個 \(8\times 8\) 的棋盤,問馬從起點到終點的最短步數為多少。

\(\sf Solution\)

要求最短路徑嘛,顯然 bfs 更優。

讀入

這個讀入處理有點麻煩……

我們可以把表示行的字元轉化為數字,即 ch-'a'+1

搜尋

將起點入隊,每次獲取隊首元素並相應擴充套件,記錄步數。

搜到的第一條路徑就是最短路徑,直接輸出 step 。

\(\sf Code\)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
struct node
{
	int x,y,step;
} o;
queue<node>q;
int dx[8]={-1,1,-1,1,-2,2,-2,2},
	dy[8]={-2,2,2,-2,-1,1,1,-1};//馬的八個方向
bool vis[10][10];//標記陣列
int sx,sy,ex,ey,xx,yy;
char ch;
string qx,qy;
int main()
{
	while(cin>>qx&&qx[0]!=EOF)
	{
		cin>>qy;
		sx=qx[0]-'a'+1,sy=qx[1]-'0';
		ex=qy[0]-'a'+1,ey=qy[1]-'0';//讀入
		memset(vis,false,sizeof(vis));//初始化
		vis[sx][sy]=true;
		q.push((node){sx,sy,0});
		while(!q.empty())
		{
			o=q.front(),q.pop();
			if(o.x==ex&&o.y==ey)//找到路徑
			{
				cout<<"To get from "<<qx<<" to "<<qy<<" takes "<<o.step<<" knight moves.\n";
				break;
			}
			for(int i=0;i<8;++i)//擴充套件
			{
				xx=o.x+dx[i],yy=o.y+dy[i];
				if(xx<=0||yy<=0||xx>8||yy>8)
					continue;
				if(vis[xx][yy])
					continue;//不符合要求的情況都排除
				vis[xx][yy]=true,q.push((node){xx,yy,o.step+1});
			}
		}
		while(!q.empty())
			q.pop();//別忘記清空佇列
	}
	return 0;
}