链接:https://ac.nowcoder.com/acm/contest/301/F
来源:牛客网
小乐乐一天天就知道玩,这一天又想玩象棋。
我们都知道马走日。
现在给定一个棋盘,大小是n*m,把棋盘放在第一象限,棋盘的左下角是(0,0),右上角是(n - 1, m - 1);
小乐乐想知道,一个马从左下角(0, 0)开始,走了k步之后,刚好走到右上角(n - 1, m - 1)的方案数。
输入描述:
输入:多组样例输入,每组一行,三个整数n, m, k(1 <= n, m, k <= 200),如题目所示。
输出描述:
输出:输出答案 mod 1000000007
示例1
输入
4 4 2
输出
2
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int dir[8][2]={2,1,2,-1,1,2,1,-2,-2,-1,-2,1,-1,2,-1,-2};
int ei,ej;
const int mod=1e9+7;
const int maxn=2e2+10;
bool vis[maxn][maxn];
typedef long long ll;
ll dp[maxn][maxn][maxn];
int n,m,k;
struct node
{
int x,y,t;
node(int x,int y,int t)
{
this->x=x;
this->y=y;
this->t=t;
}
node(){
}
};
ll dfs(int x,int y,int k1)
{
if(dp[x][y][k1]!=-1) return dp[x][y][k1];//dp这个可以解决大量时间,原来如此 ,记忆化搜索
if(k1==k)
{
if(x==ei&&y==ej) return 1;
else return 0;
}
ll ans=0;
for(int i=0;i<8;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(0<=xx&&xx<n&&0<=yy&&yy<m)
{
ans=(ans+dfs(xx,yy,k1+1))%mod;
}
}
dp[x][y][k1]=ans;
return ans;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
ei=n-1,ej=m-1;
memset(dp,-1,sizeof(dp));
printf("%lld\n",dfs(0,0,0)%mod);
}
}