問題描述
Description
只有一個馬了,又只剩下一個將,兩個棋子都在棋盤的一邊,馬不能出這一半棋盤的範圍,棋盤的大小(n行m列)。想知道他的馬最少需要跳幾次才能吃掉將(我們假定其不會移動)。
Input
每組數據一行,分別爲六個用空格分隔開的正整數n,m,x1,y1,x2,y2分別代表棋盤的大小n,m,以及將的座標和馬的座標。(1<=x1,x2<=n<=20,1<=y1,y2<=m<=20,將和馬的座標不相同)
Output
輸出對應也有若干行,請輸出最少的移動步數,如果不能吃掉將則輸出“-1”(不包括引號)。
Sample Input
8 8 5 1 4 5
Sample Output
3
我的思路
本題特色: 馬的行走方式 防止蹩腳 用了四個 if 解決
這題是學習BFS的基礎題 類似於搜索迷宮 只是把棋子換成了馬 跳轉方式不一樣 本題同樣可以適用DP方法解決 所以 對於初學者 建議先學習BFS解法 再經過少量改動達到DP的方法 系統的學習ACM算法
[AC代碼]
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cmath>
#define LL long long
#define fi first
#define se second
#define IO; std::ios::sync_with_stdio(false);std::cin.tie(0);
//降低輸入輸出時間
using namespace std;
const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double PI = acos(-1);
/**********BFS模板**********/
const int maxn=100;
bool vst[maxn][maxn]; // 訪問標記
int t[maxn][maxn];//存放最小層數
int dir[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{-1,2},{1,-2},{-1,-2}}; // 方向向量
int res;//結果層數
int n,m,xm,ym,xj,yj;//輸入量
struct State // BFS 隊列中的狀態數據結構
{
int x,y; // 座標位置
int Step_Counter; // 搜索步數統計器
};
State a[maxn];
bool CheckState(State s) // 約束條件檢驗
{
if(vst[s.x][s.y]==0 && s.x>=0 && s.x<n && s.y>=0 && s.y<m) // 滿足條件
return 1;
else
return 0;
}
void bfs(State st)
{
memset(vst,0,sizeof(vst));
queue <State> q; // BFS 隊列
State now,next; // 定義2 個狀態,當前和下一個
st.Step_Counter=0; // 計數器清零
q.push(st); // 入隊
vst[st.x][st.y]=1; // 訪問標記
while(!q.empty())
{
now=q.front(); // 取隊首元素進行擴展
if(now.x==xj&&now.y==yj) // 出現目標態,此時爲Step_Counter 的最小值,可以退出即可
{
res=now.Step_Counter;// 結果
return;
}
for(int i=0;i<8;i++)
{
next.x=now.x+dir[i][0]; // 按照規則生成下一個狀態
next.y=now.y+dir[i][1];
next.Step_Counter=now.Step_Counter+1; // 計數器加1
//防止蹩腳
if(dir[i][0]==2 && now.x+1==xj && now.y==yj ) continue;
if(dir[i][0]==-2 && now.x-1==xj && now.y==yj ) continue;
if(dir[i][1]==2 && now.x==xj && now.y+1==yj) continue;
if(dir[i][1]==-2 && now.x==xj && now.y-1==yj) continue;
if(CheckState(next)) // 如果狀態滿足約束條件則入隊
{
t[next.x][next.y]=min(t[next.x][next.y],t[now.x][now.y]+1);
q.push(next);
vst[next.x][next.y]=1; //訪問標記
}
}
q.pop(); // 隊首元素出隊
}
return;
}
void csh()
{
for(int i=0;i<100;i++)
for(int j=0;j<100;j++)
t[i][j]=inf;
}
int main()
{
IO;
while(cin>>n>>m>>xj>>yj>>xm>>ym)
{
csh();
xj--,yj--,xm--,ym--;
t[xm][ym]=0;
State st;
st.x=xm;st.y=ym;
bfs(st);
if (t[xj][yj]==inf) cout<<"-1"<<endl;
else cout<<res<<endl;//或者cout<<t[xj][yj]<<endl;
}
return 0;
}