HUST軟體與微電子學院第八屆程式設計競賽-小樂樂下象棋
阿新 • • 發佈:2018-12-04
這題其實很簡單,我們可以用一個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; }