过河卒 蓝桥杯 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的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯之算法模板题 Python版

蓝桥杯真题2021年蓝桥杯省赛A组题目解析+代码(python组)

[蓝桥杯Python]算法练习算法基础算法训练算法模板(持续更新)

蓝桥杯选拔赛真题07python杨辉三角形 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

2020年第十一届蓝桥杯 - 省赛 - Python大学组 - D.蛇形填数

蓝桥杯国赛真题08python约分 蓝桥杯青少年组python编程 蓝桥杯国赛真题解析