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;
}

猜你喜欢

转载自blog.csdn.net/qq_41090676/article/details/84786184
今日推荐