[NOIP2017 普及组] 棋盘——深搜 详解

2023-12-14 16:20
文章标签 详解 普及 棋盘 noip2017

本文主要是介绍[NOIP2017 普及组] 棋盘——深搜 详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目背景

NOIP2017 普及组 T3

题目描述

有一个 m×m 的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、下、左、右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 1 个金币。

另外, 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?

输入格式

第一行包含两个正整数 m,n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。

接下来的 n 行,每行三个正整数 x,y,c, 分别表示坐标为 (x,y) 的格子有颜色 c。

其中 c=1 代表黄色,c=0 代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标 (1,1),右下角的坐标为 (m,m)。

棋盘上其余的格子都是无色。保证棋盘的左上角,也就是 (1,1) 一定是有颜色的。

输出格式

一个整数,表示花费的金币的最小值,如果无法到达,输出 -1

输入输出样例

输入 #1

5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0

输出 #1

8

输入 #2

5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0

输出 #2

-1

说明/提示

样例 1 说明

棋盘的颜色如下表格所示,其中空白的部分表示无色。

从 (1,1) 开始,走到 (1,2) 不花费金币。

从 (1,2) 向下走到 (2,2) 花费 1 枚金币。

从 (2,2) 施展魔法,将 (2,3) 变为黄色,花费 2 枚金币。

从 (2,2) 走到 (2,3) 不花费金币。

从 (2,3) 走到 (3,3) 不花费金币。

从 (3,3) 走到 (3,4) 花费 1 枚金币。

从 (3,4) 走到 (4,4) 花费 1 枚金币。

从 (4,4) 施展魔法,将 (4,5) 变为黄色,花费 2 枚金币。

从 (4,4) 走到 (4,5) 不花费金币。

从 (4,5) 走到 (5,5) 花费 1 枚金币。

共花费 88 枚金币。

样例 2 说明

棋盘的颜色如下表格所示,其中空白的部分表示无色。

  

从 (1,1) 走到 (1,2),不花费金币。

从 (1,2) 走到 (2,2),花费 1 金币。

施展魔法将 (2,3) 变为黄色,并从 (2,2) 走到 (2,3) 花费 2 金币。

从 (2,3) 走到 (3,3) 不花费金币。

从 (3,3) 只能施展魔法到达 (3,2),(2,3),(3,4),(4,3)。

而从以上四点均无法到达 (5,5),故无法到达终点,输出−1。

数据规模与约定

对于 30% 的数据,1≤m≤5,1≤n≤10。

对于 60% 的数据,1≤m≤20,1≤n≤200。

对于 1100% 的数据,1≤m≤100,1≤n≤1,000。

分析

深度优先搜索算法

代码具体分析

1.头文件和命名空间

使用了万能头文件,包含了所有的标准库头文件,方便编写代码。

同时使用了命名空间std,避免了重名问题。

2.变量解释

二维数组a和v,分别表示迷宫的颜色和每个格子到起点的最小金币花费

dir数组,表示四个方向的移动

m和n,分别表示迷宫的大小和颜色变化的数量

ans,表示到达终点的最小金币花费,初始化为一个很大的数

3.深度优先搜索

这里使用了深度优先搜索算法

  • 从起点开始搜索,每次尝试往上下左右四个方向走到下一个格子。
  • 如果下一个格子是无色,则花费2个金币改变颜色;如果下一个格子是有色,则花费1个金币改变颜色
  • 如果颜色和上一个格子不同,则花费1个金币。
  • 如果下一个格子是终点,则判断最后一个格子的颜色是否和上一个格子的颜色不同,如果不同,则花费1个金币
  • 如果当前金币花费已经大于等于到达该格子的最小金币花费或者大于等于到达终点的最小金币花费,则剪枝。否则,更新到达该格子的最小金币花费,并继续搜索下一个格子。

4.主函数

首先输入迷宫的大小和颜色变化的数量,然后初始化a数组为-1,表示刚开始都是无色

初始化v数组为一个很大的数,表示到达每个格子的最小金币花费

接着输入每个格子的颜色,更新a数组

最后调用dfs函数,从起点开始搜索。如果到达终点的最小金币花费为一个很大的数,则输出-1,否则输出到达终点的最小金币花费

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int a[N][N],v[N][N];
int dir[4][2]={-1,0,0,1,1,0,0,-1}; 
int m,n,ans=0x3f3f3f3f;
//搜索单元格是(x,y),从(1,1)到达(x,y)已用到的金币数量是val
//(x,y)的上一个单元格的颜色是c,(x,y)的上一单元是否使用了魔法 
void dfs(int x,int y,int val,int c,int mo){if(a[x][y]==-1&&mo) return;//不能连续使用魔法if(x==m&&y==m){//到达终点 if(a[m][m]!=c){//最后一个和上一个颜色不一样 val++;if(a[m][m]==-1) val++; } if(val<ans)  ans=val;return;} if(a[x][y]==-1){//无色 val+=2;mo=1; }else{//有色 mo=0;if(a[x][y]!=c){val+=1;c=a[x][y];}}//尝试往上下左右四个方向走到下一个格子 if(val>=v[x][y]||val>=ans){//剪枝 return;}else{v[x][y]=val;//记忆化 for(int i=0;i<4;i++){int xx=x+dir[i][0],yy=y+dir[i][1];if(xx>=1&&xx<=m&&yy>=1&&yy<=m)dfs(xx,yy,val,c,mo);}}
}
int main(){cin>>m>>n;memset(a,-1,sizeof a);//-1表示刚开始都是无色 memset(v,0x3f,sizeof v);int x,y,k;for(int i=1;i<=n;i++){cin>>x>>y>>k;a[x][y]=k;//(x,y)的颜色是k }dfs(1,1,0,a[1][1],0); if(ans==0x3f3f3f3f) cout<<-1;else cout<<ans;return 0;
}

这篇关于[NOIP2017 普及组] 棋盘——深搜 详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3