洛谷趣题【过河卒】参考题解

2023-10-30 04:20

本文主要是介绍洛谷趣题【过河卒】参考题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

今天逛洛谷才注意到这道题,原题连接【P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)】

对于爱下棋的我来说,当然是必刷之题。

题意

小卒起始点在左上角(0,0)处,我们的程序将接收两个坐标:小卒目标点右下角(end_x,end_y)、以及敌方馬的坐标点(horse_x,horse_y)。

其中,小卒只可以往右或者往下走一格,并且不能经过馬脚和馬位,最多九个点不能经过。

求从左上角到右下角一共有多少种方案。数据量约定坐标最大值不超过20。

解析

乍一看,我们都知道这个应该就是一个递推算法的考察题,其中目标点的方案数求解公式应该是

res(end_x,end_y)=res(end_x-1,end_y)+res(end_x,end_y-1)

其中res(0,0)=1

我们从(0,0)出发,使用队列这个先进先出的数据结构可以有效解决这个问题。

由于一个点可能由于两个点到达,为了去重,我们需要使用一个标记数组flag和双队列,使得每个点只会入队最多一次。

考虑到有敌方馬的存在,我们给馬脚和馬位打上负值,每次经过这些负值位置则不入队,否则入队并标记这个位置,下次再搜索到这个位置时,只增加方案数,并不继续入队。

到队列全空时,结果就出来了,正是res(end_x,end_y)

时间复杂度O(n^2),空间复杂度O(n^2)

代码

#include<bits/stdc++.h>
using namespace std;class point {public:int x,y;
};int main() {int start_x=0,start_y=0;int horse_x,horse_y;int end_x,end_y;cin>>end_x>>end_y>>horse_x>>horse_y;long long res[21][21]= {0};res[0][0]=1;bool flag[21][21]= {0};int horse_direct[][2]= {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};res[horse_x][horse_y]=-1;for(int k=0; k<8; k++) {int x=horse_x+horse_direct[k][0];int y=horse_y+horse_direct[k][1];if(x>=0&&y>=0&&x<=end_x&&y<=end_y) {res[x][y]=-1;}}int soldier_direct[][2]= {{0,1},{1,0}};queue<point> q;q.push({start_x,start_y});while(!q.empty()) {queue<point> nq;memset(flag,0,sizeof(flag));while(!q.empty()) {point p=q.front();q.pop();for(int k=0; k<2; k++) {int x=p.x+soldier_direct[k][0];int y=p.y+soldier_direct[k][1];if(x<0||y<0||x>end_x||y>end_y) {continue;}if(res[x][y]<0) {continue;}res[x][y]+=res[p.x][p.y];if(!flag[x][y]) {nq.push({x,y});flag[x][y]=1;}}}q=nq;}cout<<res[end_x][end_y]<<endl;return 0;
}

提交

这篇关于洛谷趣题【过河卒】参考题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/305546

相关文章

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例 3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例 4.基于SSM的高校实验室管理系统+LW参考示例 5.基于SpringBoot的二手数码回收系统+原生微信小程序+LW参考示例 6.基于SSM的民宿预订管理系统+LW参考示例 7.基于

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

2024 年高教社杯全国大学生数学建模竞赛 C 题 农作物的种植策略 参考论文 无水印

持续更新中,2024年数学建模比赛思路代码论文都会发布到专栏内,只需订阅一次!  完整论文+代码+数据结果链接在文末!  订阅后可查看参考论文文件 第一问 1.1 问题重述 这个问题围绕的是华北山区的某乡村,在有限的耕地条件下,如何制定最优的农作物种植策略。乡村有 34 块露天耕地和 20 个大棚,种植条件包括粮食作物、蔬菜、水稻和食用菌。除了要考虑地块的面积、种植季节等,还要确保

P2858 [USACO06FEB] Treats for the Cows G/S 题解

P2858 题意 给一个数组。每天把最左或者最右的东西卖掉,第 i i i个东西,第 d a y day day天卖出的价格是 a [ i ] ∗ d a y a[i]*day a[i]∗day。 记忆化搜索 void dfs(int l,int r,int day,ll sum){if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r)//这就是dp答案{

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=