哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级)F-小乐乐下象棋

14 篇文章 0 订阅

链接: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 <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <vector>
#include <cstdio>
#include <cmath>
#define ll long long
#define lowbit(x)  (x&(-x))
#define pi acos(-1.0) 
#define N 202
const ll mod=1e9+7;
using namespace std;
ll dir[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
ll n,m,k;
ll dp[N][N][N];
int judge(ll x,ll y)
{
	if(x<0||y<0||x>=n||y>=m) return 0;
	return 1;
}
ll dfs(ll x,ll y,ll cnt)
{
	if(dp[x][y][cnt]!=-1) return dp[x][y][cnt];
	if(cnt==k) 
	{
		if(x==n-1&&y==m-1) return 1;
		return 0;
	 }
	ll ans=0;
	for(int i=0;i<=7;i++)
	{
		ll fx=x+dir[i][0];
		ll fy=y+dir[i][1];
		if(judge(fx,fy))
		{
			ans=(ans+dfs(fx,fy,cnt+1))%mod;
		}
	}
	dp[x][y][cnt]=ans;
	return ans; 
}
int main()
{
	while(cin>>n>>m>>k)
	{
		memset(dp,-1,sizeof(dp));
		cout<<dfs(0,0,0)<<endl; 
	}
	return 0;
	
}

 

 Bfs

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <vector>
#include <cstdio>
#include <cmath>
#define ll long long
#define lowbit(x)  (x&(-x))
#define pi acos(-1.0) 
#define N 202
const ll mod=1e9+7;
using namespace std;
ll dir[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
ll n,m,k;
ll dp[N][N][N];
int vis[N][N][N];
struct Node
{
	int x,y,step;
//	Node()
//	{
//		x=0;
//		y=0;
//		step=0;
//	 } 
 }; 
void bfs()
{
	queue<Node> que;
	while(!que.empty()) que.pop();
	que.push({0,0,0});
	memset(vis,0,sizeof(vis));
	memset(dp,0,sizeof(dp));
	vis[0][0][0]=1;
	dp[0][0][0]=1;
	while(!que.empty())
	{
		Node to=que.front();
		que.pop();
		if(to.step==k) continue;
		for(int i=0;i<8;i++)
		{
			int dx=to.x+dir[i][0];
			int dy=to.y+dir[i][1];
			if(dx<0||dx>=n||dy<0||dy>=m) continue;
			dp[dx][dy][to.step+1]=(dp[dx][dy][to.step+1]+dp[to.x][to.y][to.step])%mod;
			if(vis[dx][dy][to.step+1]) continue;
			vis[dx][dy][to.step+1]=1;
			que.push({dx,dy,to.step+1});
		}
	}
	
}
int main()
{
	while(cin>>n>>m>>k)
	{
		bfs();
		cout<<dp[n-1][m-1][k]<<endl;
	}
	return 0;
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值