过河卒 蓝桥杯 755
Posted 小梁今天敲代码了吗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过河卒 蓝桥杯 755相关的知识,希望对你有一定的参考价值。
题目描述
如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。
例如上图 C 点上的马可以控制 99 个点(图中的 P1,P2,⋯P8 和 �C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)(0,0)、B 点(n,m)(n,m≤20),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。。
输入描述
一行四个正整数,分别表示 B 点坐标和马的坐标。
输出描述
一个整数,表示所有的路径条数。
输入输出样例
示例 1
输入
6 6 3 3
输出
6
思路:这道题如果用dfs,复杂度太高,所以用动态规划,每步更新相应格子的dp数组,一直到终点B
如何判断这一点是否是马能走的点? 根据题意,马能走到相距两格的对角线位置,即如果相对于马的坐标(x,y)来说,它能走到的就是(x-2,y-1),(x-2,y+1),(x+2,y-1),(x+2,y+1),(x+1,y-2),(x+1,y+2),(x-1,y+2),(x-1,y-2)这八个点,也就是说在矩阵中对于马的坐标来说,这八个点不能走,我们可以将这八个点的dp[i][j]置0
还有需要注意的是:对于这道题来说,如果马的坐标在第一行和第二行,那么它可跳跃的坐标有可能为负数,为了避免这种情况的出现,我们可以给矩阵中的所有点横纵坐标+2
此时起点坐标为(2,2)
dp表达式为
当[i][j]不能走时,dp[i][j]=0
当[i][j]能走时,dp[i][j]=dp[i-1][j]+dp[i][j-1]
dp=[[0]*25 for i in range(25)]
s=[[0]*25 for i in range(25)]
bx,by,mx,my = map(int,input().split())
bx+=2
by+=2
mx+=2
my+=2
dp[2][1]=1#初始化dp数组,在下面求dp[2][2]时用到
s[mx][my]=1
s[mx-2][my-1]=1
s[mx+2][my-1]=1
s[mx+2][my+1]=1
s[mx-2][my+1]=1
s[mx-1][my+2]=1
s[mx-1][my-2]=1
s[mx+1][my+2]=1
s[mx+1][my-2]=1
for i in range(2,bx+1):
for j in range(2,by+1):
if s[i][j]==1:
dp[i][j]=0
else:
dp[i][j]=dp[i-1][j]+dp[i][j-1]
print(dp[bx][by])
过河卒(BFS)
过河卒
Time Limit: 5000 MS Memory Limit: 65536 K
Total Submit: 296(91 users) Total Accepted: 73(56 users) Rating: Special Judge: No
Description
Lda学会了中国象棋,在一次与Kevin的切磋中,Lda不幸只剩下一只过河卒了,而Kevin还有很多棋子。
过河卒在棋盘上能移动的范围是一个5×9的平面(如图)。据Kevin介绍,过河卒每一步都可以选择向前、左、或右移一格,但是不能后退,也不能移出棋盘边界。途中如果经过敌人的棋子,那么敌人的棋子就被吃掉了。
考虑到Lda初学,为了能让游戏不至于过快结束,Kevin决定让Lda的过河卒连走k步,在这k步中Kevin不走棋。Lda希望在这k步中他能吃掉尽可能多的棋子,请问他最多能吃掉Kevin多少棋子呢?
Input
第一行一个正整数T,表示测试数据的组数。接下来每组数据第一行一个正整数k (k ≤ 100),表示Lda可以连续走棋的步数。然后接下来的5行表示棋盘状态,每行一个9个字符的字符串,其中’*’表示没有棋子,’K’表示有Kevin的棋子,’L’表示这里是Lda的过河卒的初始位置(棋盘上有且只有一个’L’)
Output
每组数据输出一行,表示Lda最多能吃掉的棋子数。
Sample Input
3
5
**KKK****
****K****
**K*K**K*
KK****L**
**K******
9
*********
**K******
*********
**K****K*
******L**
8
*********
**K******
*********
**K****K*
******L**
Sample Output
3
3
2
过河卒
这道题利用BFS求解,但是要注意剪枝。不然会造成时间超限,只有和dx处于同行的才有可能进行两次查找,不然只进行一次就行了,不用进行重复查找。
#include<bits/stdc++.h>
using namespace std;
#define CHECK(x,y)(x>=0&&x<5&&y>=0&&y<9)
char room[5][9];
int vis[5][9];
int num,k,sum;
int dx,dy,flag;
struct node
int x,y;
;
void BFS(int x,int y,int step,int food)
//cout<<x<<' '<<y<<' '<<food<<endl;
if(step==k)
if(food>num)
num=food;
return;
if(food==sum)
num=sum;
flag=1;
return;
if(flag==1)return;
if(step>(dx+1-x)*9+min(dy,8-dy))
return;
node start,next;
start.x=x;
start.y=y;
for(int i=0;i<3;i++)
if(i==0)
next.x=start.x-1;
next.y=start.y;
else if(i==1)
next.x=start.x;
next.y=start.y-1;
else
next.x=start.x;
next.y=start.y+1;
if(CHECK(next.x,next.y)&&((next.x==dx&&vis[next.x][next.y]<2)||(next.x!=dx&&vis[next.x][next.y]<1)))
vis[next.x][next.y]++;
if(room[next.x][next.y]=='K')
room[next.x][next.y]='*';
BFS(next.x,next.y,step+1,food+1);
room[next.x][next.y]='K';
else
BFS(next.x,next.y,step+1,food);
vis[next.x][next.y]--;
int main()
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)
memset(vis,0,sizeof vis);
sum=0;
dx=10;
flag=0;
cin>>k;
for(int i=0;i<5;i++)
for(int j=0;j<9;j++)
cin>>room[i][j];
if(room[i][j]=='L')
dx=i;
dy=j;
if(room[i][j]=='K'&&dx>=i)
sum++;
vis[dx][dy]=1;
//cout<<sum<<endl;
if(sum==0)
cout<<0<<endl;
else
k=min((dx+2)*9,k);
num=0;
BFS(dx,dy,0,0);
cout<<num<<endl;
return 0;
以上是关于过河卒 蓝桥杯 755的主要内容,如果未能解决你的问题,请参考以下文章
蓝桥杯真题2021年蓝桥杯省赛A组题目解析+代码(python组)
[蓝桥杯Python]算法练习算法基础算法训练算法模板(持续更新)
蓝桥杯选拔赛真题07python杨辉三角形 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析