CSUOJ1224 BFS模板加實例 ACM小組的古怪象棋

問題描述

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章