1. 程式人生 > >HUST軟體與微電子學院第八屆程式設計競賽-小樂樂下象棋

HUST軟體與微電子學院第八屆程式設計競賽-小樂樂下象棋

這題其實很簡單,我們可以用一個bfs搜尋出所有的,小於k步的,到不同點不同步數的方案數。

我們首先初始化,走到(0,0)點的時候,我們把步數設定為0,但是方法數設定為1,這是因為我們走零步,到一個點,確實有一種方法。

然後就是bfs,當步數等於k的時候,我們就跳過這點,因為題目中要求是等於k步,即使你搜了大於k步的方案數,我們也用不著。

越界判斷之後,我麼先加上從別的點到達下一個點的方案數,取模之後,我們再判斷這點我們是否在current.step+1的基礎上走過我們準備走的下一點。

這也就是說,我們是否曾經已經用相通的步數走過這點,第一次肯定是沒有走過的,但是如果之後也走出了這種情況,我們就continue了,我們已經把這個點放進去過隊列了,我們就不再重複搜尋。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
 
const int mod=1e9+7;
const int maxn=205;
int Dx[8] = {2, 2, -2, -2, 1, -1, 1, -1};
int Dy[8] = {1, -1, 1, -1, 2, 2, -2, -2};
 
struct Status
{
    int x,y;
    int Step;
    Status(int a,int b,int c):x(a),y(b),Step(c){}
};
 
int n,m,k;
int visited[maxn][maxn][maxn];
int dp[maxn][maxn][maxn];
queue <Status> q;
 
void bfs()
{
    while (!q.empty()) {
        Status cur=q.front();
        q.pop();
        if (cur.Step==k)
            continue;
        for (int i=0;i<8;i++) {
            int dx=cur.x+Dx[i];
            int dy=cur.y+Dy[i];
            if (dx<0||dy<0||dx>=n||dy>=m)
                continue;
            dp[dx][dy][cur.Step+1]+=dp[cur.x][cur.y][cur.Step];
            dp[dx][dy][cur.Step+1]%=mod;
            if (visited[dx][dy][cur.Step+1])
                continue;
            q.push(Status(dx,dy,cur.Step+1));
            visited[dx][dy][cur.Step+1]=1;
        }
    }
}
 
int main()
{
    while (~scanf("%d%d%d,",&n,&m,&k)) {
        memset(visited,0,sizeof(visited));
        memset(dp,0,sizeof(dp));
        q.push(Status(0,0,0));
        visited[0][0][0]=1;
        dp[0][0][0]=1;
        bfs();
        cout<<dp[n-1][m-1][k]<<endl;;
    }
    return 0;
}