c++ bfs基本應用
Knight Moves
題目描述
貝茜和她的表妹在玩一個簡化版的國際象棋。棋盤如圖所示:
貝茜和表妹各有一顆棋子。棋子每次移一步,且棋子只能往如圖所示的八個方向移動。比賽的規則很簡單,兩個人需要從起點將棋子移到終點,誰能花最少的步數從起點走到終點,就是贏家。
為了確保能贏表妹,貝茜希望每次都能算出最少的步數,你能幫助她麼?
輸入
輸入起點和終點,用一個空格隔開。(確保起點一定能走到終點)
輸出
輸入最少的步數。
樣例輸入
a1 b2
樣例輸出
4
上程式碼:
AC程式碼
#include <bits/stdc++.h>
using namespace std;
struct Point
{
int x,y,step;
};
Point q[1000000],s,t;//t是終點,s是起點
int dx[8]={1,-1,1,-1,2,2,-2,-2};//dx[] + dy[] 代表Knight走的8個方向可達的點
int dy[8]={2,2,-2,-2,1,-1,1,-1};
int f=1,e=0;
int main()
{
char ca,cb,cc,cd;
scanf("%c%c %c%c",&ca,&cb,&cc,&cd);//輸入
s.x=ca-'a'+1,s.y=cb-'1'+1;s.step=0;//把a轉換成數字1 把字元1轉換成數字1
t.x=cc-'a'+1,t.y=cd-'1'+1;t.step = 0;//把b轉換成數字2 把字元2轉換成數字2
if(s.x==t.x&&s.y==t.y)//如果起點等於終點,就直接退出
{
printf("0\n");
return 0;
}
e++;//佇列入隊時候的下標
q[e]=s;//q就是佇列 把所有待查詢的元素放在q佇列裡面
while(f<=e)//出隊的下標不能大於入隊時候的下標
{
Point u=q[f];//f是佇列出隊時候的下標 //* u是在佇列中選定的騎士 *//
for(int i=0;i<8;i++)//for迴圈為了能 加上dx[] 和dy[]
{
Point v;//v是有效的騎士
v.x = u.x + dx[i],v.y = u.y + dy[i],v.step=u.step + 1;//把選定的位置向8個方向擴充套件(一次)
if(v.x<1||v.x>8||v.y<1||v.y>8)continue;//如果這個騎士的位置不在棋盤上,則丟棄
if(t.x==v.x&&t.y==v.y)//找到了終點
{
printf("%d\n",v.step);//輸出步數
return 0;
}
e++;// 把入隊下標 + 1
q[e]=v;// 入隊
}
f++;//出隊下標 + 1
}
return 0;
}