牛客——扫雷MINE(dp,dfs,枚举+递推)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

相信大家都玩过扫雷的游戏。那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来。

万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字 表示和它8连通的格子里面雷的数目。

现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图: 由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放方案。

输入描述:

第一行为N,第二行有N个数,依次为第二列的格子中的数。(1 ≤ N ≤ 10000)

输出描述:

一个数,即第一列中雷的摆放方案数。

#include <iostream>
#include <cstdio>
using namespace std;const int mxn = 10010;
int n;
int f[mxn][4], g[mxn];int main() {int n;cin>>n;for (int i = 1; i <= n; ++i)cin>>g[i];if (g[1] == 0) f[1][0] = 1;else if (g[1] == 1) f[1][1] = f[1][2] = 1;else if (g[1] == 2) f[1][3] = 1;for (int i = 2; i < n; ++i) {if (g[i] == 0) f[i][0] = f[i-1][0];if (g[i] == 1) {f[i][0] += f[i-1][2];f[i][1] += f[i-1][0];f[i][2] += f[i-1][1];}if (g[i] == 2) {f[i][1] += f[i-1][2];f[i][2] += f[i-1][3];f[i][3] += f[i-1][1];}if (g[i] == 3)f[i][3] = f[i-1][3];}if (g[n] == 1)cout<< f[n-1][1] + f[n-1][2]<<endl;if (g[n] == 2) cout<<f[n-1][3]<<endl;if (g[n] == 3)cout<<'0'<<endl;if (g[n] == 0)cout<<f[n-1][0]<<endl;return 0;
}

以上的代码我搜了一下其他人写的,感觉好难想啊,这个是题解的链接:https://www.cnblogs.com/bbqub/p/8425718.html

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10004];
int f[10004],n,i,j,ans,flag;
int hi(){for(int j=2;j<n;j++){//从2开始判断int t=a[j]-f[j-1]-f[j];//判断第i+1处是否有雷if(t<0 || t>1)  return 0;//不符合标准else    f[j+1]=t;}if(f[n]+f[n-1]!=a[n]){//特批一下最后两个return 0;}return 1;
}
int main()
{scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]>3) flag=1;}if(a[1]>2 || a[n]>2 || flag){printf("0\n");return 0;}if(a[1]==2){f[1]=1;f[2]=1;ans+=hi();}else if(a[1]==0){f[1]=0;ans+=hi();}else if(a[1]==1){f[1]=1;//地雷放第一个ans+=hi();memset(f,0,sizeof(f));f[2]=1;//地雷放第二个ans+=hi();}printf("%d",ans);
}

这个会容易理解些:

a[i]:第二列第i个数的值
f[i]:第一列的i个数是否有雷,1代表有,0代表无
f[i-1]+f[i]+f[i+1]=a[i]-->f[i+1]=a[i]-f[i-1]-f[i](扫雷规则)

先整体来看,显然对于每个a[i]的值均不能超过3,因为棋盘只有一列有雷,即以某点为中心最多只有3颗雷,特别的,第一个数和最后一个数不能超过2,因为有一个被挡住了。按顺序先从第一个值进行考虑,共有3种可能,0,1,2。
如果第一个数为0:第一列第1,2个位置可推出没有雷,通过f[i+1]=a[i]-f[i-1]-f[i]递推下去每个位置是否有雷为固定答案。
如果第一个数为2:第一列的第1,2个位置可推出均为雷,同上式可推出每个位置是否有雷为固定答案。
如果第一个数为1:那么则可能有2个答案,第一列的第1个位置有雷或者是第二个位置有雷,当其中一个位置有雷,即可推出另一个了,已知两个位置,用上面的递推式即可确定之后是否有雷了。

最后把其他格子的数枚举判断是否合法即可ac了。

#include<bits/stdc++.h>
using namespace std;
#define maxn 10004
int n;
int a[maxn],b[maxn];
int ans;
void dfs(int x)
{int sum=0;if(b[x-1]) sum++;if(b[x]) sum++;if(sum==a[x]-1)//下一个点必须是地雷{if(x+1 > n) return ; b[x+1]=1;//有地雷dfs(x+1);b[x+1]=0;}if(sum!=a[x]) return;if(x==n){ans++;return;}dfs(x+1);//没有地雷。
}int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);b[1]=1;dfs(1);memset(b,0,sizeof(b));dfs(1);printf("%d\n",ans);return 0;
}

上面的用dfs暴瘦一下,每个点只能是有或者没有地雷,按照这两个状态进行搜索即可。
每次枚举完记得判断一下是否为可行解,进行剪枝。
注意一下第一个点要分类讨论放不放地雷。

突然发现想复杂了其实,看了大佬的代码是这样的:

#include<iostream>
using namespace std;
int n,a[10005],f[10005],ans=0;
int main()
{cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=0;i<=a[1];i++){f[1]=i;for(int j=2;j<=n+1;j++)f[j]=a[j-1]-f[j-1]-f[j-2];if(f[n+1]==0) ans++;}cout<<ans;
}
#include<iostream>
using namespace std;
const int N=1e5+10;
int ans;
int a[N];
int n;
void dfs(int x,int lst,int now){if(x== n+1 && now==0 ) {ans++;return;}if(now + lst > a[x]) return ;dfs(x+1,now,a[x]-lst-now);
}
int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];dfs(1,0,1);dfs(1,0,0);cout<<ans<<"\n";return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,a[N],f[N],ans;
bool check(){for(int i=2;i<=n;i++){f[i]=a[i-1]-f[i-1]-f[i-2];if(f[i]<0||f[i]>1) return 0;}return a[n]==f[n]+f[n-1];
}
int main()
{cin>>n;for(int i=1;i<=n;i++) cin>>a[i];f[1]=1;if(check()) ans++;f[1]=0;if(check()) ans++;cout<<ans;
} 
#include<bits/stdc++.h>using namespace std;int n,a[2][10005];
int i;bool b(bool k){a[1][1]=k;for(i=1;i<=n;i++){if(a[1][i]+a[1][i-1]>a[0][i]){return 0;}a[1][i+1]=a[0][i]-a[1][i-1]-a[1][i];}return !a[1][n+1];
}int main()
{int i;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&a[0][i]);}printf("%d\n",b(0)+b(1));return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【BIAI】Lecture 9-Motor system 1

Motor System 专业词汇 skeletal muscle 骨骼肌 smooth muscle 平滑肌 cardiac muscle 心肌 flexor reflex 屈曲反射 central pattern generators 中央模式生成器 bio-inspired bipedal robots 仿生双足机器人 myotatic stretch reflex 肌肉自伸展反射 Cortex optic nerve 视皮…

web wifi配网和模式切换-esp8266和esp32

web wifi配网和模式切换-esp8266和esp32 支持模式:1:tcp client() 2:tcp server 3:http server(POST/GET) 4:http client 5:udp,6:factory,7:mqtt 配网进入方式&#xff1a; 开机&#xff0c;指示灯亮起后(需要灯闪烁3下后)&#xff0c;需在3s内&#xff08;超过3s则会正常启动…

NUXTJS安装始终报错无法正常运行问题解决

近日在了解NuxtJS&#xff0c;按照官方给出方法进行安装后&#xff0c;不是报错&#xff0c;就是安装成功后运行不了。执行npm run dev后始终运行出错&#xff0c;判断肯定是对应版本问题&#xff0c;沿着这方向研究&#xff0c;最终运行成功了。 文档地址&#xff1a;安装 - …

WordPress可以做企业官网吗?如何用wordpress建公司网站?

我们在国内看到很多个人博客网站都是使用WordPress搭建&#xff0c;但是企业官网的相对少一些&#xff0c;那么WordPress可以做企业官网吗&#xff1f;如何用wordpress建公司网站呢&#xff1f;下面boke112百科就跟大家简单说一下。 WordPress是一款免费开源的内容管理系统&am…

python爬虫4

#1.练习 # &#xff08;1&#xff09; 获取网页的源码 # &#xff08;2&#xff09; 解析 解析的服务器响应的文件 etree.HTML # (3) 打印 import urllib.request urlhttps://www.baidu.com/ headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit…

RabbitMQ介绍及简单操作

文章目录 一、同步调用二、异步调用三、MQ介绍1.安装RabbitMQ2.介绍RabbitMQ3.页面简单使用 一、同步调用 例如&#xff1a; #mermaid-svg-DMjF9XQ1VKYd5FjK {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-DMjF9XQ…

[Angular 基础] - Angular 渲染过程 组件的创建

[Angular 基础] - Angular 渲染过程 & 组件的创建 之前的笔记为了推进度写的太笼统了&#xff08;只有功能没有其他&#xff09;&#xff0c;当时学的时候知道是什么东西&#xff0c;但是学完后重新复习发现有些内容就记不清了&#xff0c;所以重新用自己的语言总结一下 …

Aigtek超声功率放大器的作用是什么

超声功率放大器是一种用于放大超声信号的设备&#xff0c;其作用是增强超声信号的功率&#xff0c;使其能够在超声应用中达到所需的强度和能量。下面西安安泰将详细解释超声功率放大器的作用以及其在不同领域的应用。 超声技术是通过利用超声波的高频振动传递和检测能量&#x…

springboot在线问诊系统-计算机毕业设计源码00211

摘 要 针对医院门诊等问题&#xff0c;对在线问诊进行研究分析&#xff0c;然后开发设计出在线问诊系统以解决问题。在线问诊系统主要功能模块包括首页、轮播图管理、公告信息管理、资源管理、系统用户管理&#xff08;管理员、患者用户、医生用户&#xff09;、模块管理&#…

MongoDB从入门到实战之MongoDB快速入门

前言 上一章节主要概述了MongoDB的优劣势、应用场景和发展史。这一章节将快速的概述一下MongoDB的基本概念&#xff0c;带领大家快速入门MongoDB这个文档型的NoSQL数据库。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战之MongoDB简介&#x1f449; MongoDB从入门到实战…

go_view同后端集成时的注意事项

goview是一个不错的可视化大屏配置工具;提供了丰富的功能可供调用。 官方地址和文档: https://gitee.com/dromara/go-view https://www.mtruning.club/guide/start/ 同nodejs集成可参考;https://gitee.com/qwdingyu/led (建议–后端集成有api功能,可直接配置sql)同dotne…

力扣面试题 17.11. 单词距离(双指针)

Problem: 面试题 17.11. 单词距离 文章目录 题目描述思路复杂度Code 题目描述 思路 Problem力扣面试题 16.06. 最小差 该题目只需预先做一些处理&#xff0c;即可以转换为上述题目&#xff1a; 1.预处理操作&#xff1a;定义两个数组w1ps&#xff0c;w2ps用于记录在words数组中…

【ARM Coresight 系列文章 8.1 - ARM Coresight 通过 APBIC arbiter】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 APBIC arbiter仲裁使用举例APBIC arbiter 在 SoC-600中,APBIC 是用来为 APB4 master 和 APB4 slave 提供 连接关系的组件。APB 是一种简单的总线协议,通常用于低带宽或低性能外设,如定时器、接口控制等。APBIC …

查找二叉树结点C++,数组模拟二叉树

已知一棵二叉树用邻接表结构存储&#xff0c;中序查找二叉树中权值为 x 的结点&#xff0c;并指出该结点在中序遍历中的排列位置。 例&#xff1a;如图二叉树的数据文件的数据格式如下: 输入格式 第一行包含整数 n&#xff0c;表示二叉树的结点数&#xff0c;结点编号从 1 到…

Arduino控制器使用Udp网络对8路IO输出控制

一、实现功能 1、创建串口连接&#xff0c;将接收的Udp数据通过串口发送出去。 2、创建Udp连接&#xff0c;用以接收Udp数据和对发送数据的Udp机器反馈Udp数据 3、对接收到的Udp数据进行解析&#xff0c;然后对8路IO进行输出控制。 4、1对应IO输出低电平&#xff0c;‘0’对…

stack_queue:三个关键注意事项解析

一、stack与容器 template<class T, class Container> class stack { private:Container _con; };Container 为容器&#xff0c;在实例化创建对象时&#xff0c;我们可以传 vector<T> 或 list<T> 等作为栈的底层。 举例&#xff1a; int main() {stack<i…

DES加密解密算法(简单、易懂、超级详细)

目录 一、基础补充 二、什么是DES算法 &#xff08;1&#xff09;对称加密算法 &#xff08;2&#xff09;非对称加密算法 &#xff08;3&#xff09;对称加密算法的应用 三、DES算法的基础操作步骤 1.明文的加密整体过程 2.F轮函数解析 3.密钥的形成过程 四、AC代码 五、D…

代码随想录算法训练营29期Day41|LeetCode 343,96

文档讲解&#xff1a;整数拆分 不同的二叉搜索树 343.整数拆分 题目链接&#xff1a;https://leetcode.cn/problems/integer-break/description/ 思路&#xff1a; 题目要求我们拆分n&#xff0c;拆成k个数使其乘积和最大&#xff0c;然而题目中并没有给出k&#xff0c;所以…

【Mysql】事务的隔离级别与 MVCC

事务隔离级别 我们知道 MySQL 是一个 C/S 架构的服务&#xff0c;对于同一个服务器来说&#xff0c;可以有多个客户端与之连接&#xff0c;每个客户端与服务器连接上之后&#xff0c;就是一个会话&#xff08; Session &#xff09;。每个客户端都可以在自己的会话中向服务器发…

如何使用VSCode上运行Jupyter,详细案例过程出可视化图

Python作为最受AI喜欢的语言之一&#xff0c;我们与大家共同学习下如何在VS Code上运行Jupyter&#xff0c;并且用简单案例实现出图。 环境 VS Code version: 1.80.1 Python: 3.12.0 小白安装过程&#xff1a; 在准备好基础环境&#xff0c;小白心想&#xff0c;AI可是霸占科…