[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

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMessageDialog()方法 3.1

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

OmniGlue论文详解(特征匹配)

OmniGlue论文详解(特征匹配) 摘要1. 引言2. 相关工作2.1. 广义局部特征匹配2.2. 稀疏可学习匹配2.3. 半稠密可学习匹配2.4. 与其他图像表示匹配 3. OmniGlue3.1. 模型概述3.2. OmniGlue 细节3.2.1. 特征提取3.2.2. 利用DINOv2构建图形。3.2.3. 信息传播与新的指导3.2.4. 匹配层和损失函数3.2.5. 与Super

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹