当前位置: 首页 > news >正文

【Acwing166】数独(dfs+剪枝+位运算)超级详细题解!

本题思路来源于acwing算法提高课

题目描述

看本文需要准备的知识

1.dfs算法基本思想

2.位运算基础

3.对剪枝这个名词的大概了解

剪枝优化+位运算优化

常见四种剪枝策略

首先考虑这道题的搜索顺序,很明显,可以随意选择一个空格子,分支为这个空格子可以填入的所有数字,然后对于每个分支,可以再随意选择一个空格子,继续进行上述步骤达成递归,这种搜索顺序是一定能够把每一种情况不漏地搜索到

下面考虑优化的策略:

第一个优化,优化搜索顺序,可以考虑一下,什么情况下,搜索的分支较少呢?显然是对于那些可以填的数字合法情况比较少的空格,所以我们再找下一个空格时,就优先选择这类的空格

上面的搜索顺序保证了不会有冗余,所以第二个剪枝策略用不上

第二个优化,可行性剪枝,就是说在遍历过程当中,只考虑那些合法的数字分支,即在那个空格的行、列以及九宫格上面不能有数字重复

最优性剪枝也是用不上的,因为这里面只要找到一个合法解就行了,不存在最优解的区分

第三个优化是位运算,用来做两件事情:

1.用一个9位的01串表示一行或一列或一个九宫格里面的填充情况,0表示已经填充,1表示没有填充,举一个例子,row[2]=000111010表示第二行已经用过了9,8,7,3,1,列col和九宫格cell同理,那么对于一个坐标为(x,y)的空格,怎么知道可以填哪些数字呢?只需要把对应的row、col、cell进行与运算,看一下1出现了第几位上,那么就可以填几

2.lowbit优化

lowbit是什么?是一个运算,比如lowbit(x)=x&-x

lowbit可以算出什么?比如10101可以得到1,100100可以得到100,11000可以得到1000(注意上面的都是二进制数,即得到最低位1的位置)

有了lowbit之后,对于一个空格,假设我们通过上面二进制表示的行、列、九宫格的与运算得到了一个01串:101001010,这个01串有4个1,如果直接遍历,每次都要9次,但是如果用上lowbit,只需要遍历4次即可:

lowbit(101001010)=10,第2位的1,所以可以放2

lowbit(101001000)=1000,第4位的1,所以可以放4

依次类推......

详细过程

讲解了本题的优化策略,下面来详细介绍,这道题的实现细节

首先定义6个数组:

其中三个为int row[N],col[N],cell[N][N],存放对应位置的状态

第四个是int ones[1<<N],表示某一个数的二进制表示里面有几个1

第五个是int log2[1<<N],表示某一个数的以2为底的对数,因为使用lowbit之后得到的是2的k次幂,而这个k才是我们想要的(代表1的位置),所以我们预处理这个数组,方便后续使用

第六个就是char str[100],代表所有的格子内容,包括数字和小数点(表示暂时没有填充)这两种情况

然后再写四个辅助函数,分别是init,draw,get_state,lowbit

init:初始化所有格子,暂时全部没有填过数字

draw:在(x,y)这个格子上面填上数字t(is_set==true),或者去掉数字t(is_set==false)

get_state:得到(x,y)上的行、列、九宫格的状态交集01串

lowbit:上面已经讲解过了

然后我们来说一下main函数的内容:

对于每一个样例,init初始化,然后遍历输入的str,对方格进行填充,如果遇到’.’那么就记录一下,最终统计暂未填充的格子总数,最后调用dfs,最后输出str即可

最后我们说dfs如何写:

首先参数cnt代表还剩几个空格没有填数,当cnt==0时,直接返回true即可,表示已经全部填充完毕。

然后,寻找分支数最少的空格(搜索顺序优化)

找到之后,通过get_state函数得到01串,然后利用lowbit去得到这个01串中1的每个位置,就是一个新的分支,这个遍历之后返回false保证函数代码的完整性

完整代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=9,M=1<<N;
int row[N],col[N],cell[N][N];
int ones[M],log2_map[M];
char str[100];
void init()
{for(int i=0;i<N;i++)row[i]=col[i]=(1<<N)-1;for(int i=0;i<N/3;i++){for(int j=0;j<N/3;j++)cell[i][j]=(1<<N)-1;}
}
void draw(int x,int y,int t,bool is_set)
{if(is_set)str[x*N+y]=t+'1';else str[x*N+y]='.';int r=1<<t;if(!is_set)r=-r;row[x]-=r;col[y]-=r;cell[x/3][y/3]-=r;
}
int lowbit(int x)
{return x&-x;
}
int get_state(int x,int y)
{return row[x]&col[y]&cell[x/3][y/3];
}
bool dfs(int cnt)
{if(!cnt)return true;int minx=10;int x,y;for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(str[i*N+j]=='.'){int state=get_state(i,j);if(ones[state]<minx){minx=ones[state];x=i,y=j;}}}}int state=get_state(x,y);for(int i=state;i;i-=lowbit(i)){int t=log2_map[lowbit(i)];draw(x,y,t,true);if(dfs(cnt-1))return true;draw(x,y,t,false);}return false;
}
int main()
{for(int i=0;i<N;i++)log2_map[1<<i]=i;for(int i=0;i<1<<N;i++)for(int j=0;j<N;j++)ones[i]+=(i>>j)&1;while(cin>>str,str[0]!='e'){init();int cnt=0;for(int i=0,k=0;i<N;i++){for(int j=0;j<N;j++,k++){if(str[k]!='.'){draw(i,j,str[k]-'1',true);}else cnt++;}}dfs(cnt);cout<<str<<endl;}return 0;
}

相关文章:

【Acwing166】数独(dfs+剪枝+位运算)超级详细题解!

本题思路来源于acwing算法提高课 题目描述 看本文需要准备的知识 1.dfs算法基本思想 2.位运算基础 3.对剪枝这个名词的大概了解 剪枝优化位运算优化 常见四种剪枝策略 首先考虑这道题的搜索顺序&#xff0c;很明显&#xff0c;可以随意选择一个空格子&#xff0c;分支为这…...

Docker Swarm 集群搭建

Docker Swarm Mode Docker Swarm 集群搭建 Docker Swarm 节点维护 Docker Service 创建 1.准备主机 搭建一个 docker swarm 集群&#xff0c;包含 5 个 swarm 节点。这 5 个 swarm 节点的 IP 与暂 时的角色分配如下&#xff08;注意&#xff0c;搭建完成后会切换角色&#xff…...

Mac 开机提示Google LLC 注册 无法登录进入系统

Google LLC 会在电脑启动时提示如下弹窗&#xff0c;并要求登录谷歌账户进行验证 此时很明显没有用来进行验证的账号&#xff0c;所以需要关掉这个验证程序 从日志里面可以看到LLC启动了一个Tiny.app的程序 只需要想办法把这个程序删掉即可 关机 按住 Command R 开机 进入R…...

excel单元格各种组合求和

单元格如果连续选择的话使用冒号&#xff0c;不是连续选择使用逗号&#xff1b;sum(A1:A4)表示对A1到A4求和&#xff1b;sum(A1,A4)表示求A1A4的和&#xff1b; 如下图&#xff0c;求斜线上四个单元格的和&#xff0c;结果见下图&#xff1b; 求A列和C列全部单元格的和&#x…...

SysTick—系统定时器

SysTick 简介 SysTick—系统定时器是属于CM3内核中的一个外设&#xff0c;内嵌在NVIC中。系统定时器是一个24bit 的向下递减的计数器&#xff0c;计数器每计数一次的时间为1/SYSCLK&#xff0c;一般我们设置系统时钟SYSCLK 等于72M。当重装载数值寄存器的值递减到0的时候&#…...

ATPCS:ARM-Thumb程序调用的基本规则

为了使单独编译的c文件和汇编文件之间能够互相调用&#xff0c;需要制定一系列的规则&#xff0c;AAPCS就是ARM程序和Thumb程序中子程序调用的基本规则。 1、ATPCS概述 ATPCS规定了子程序调用过程中寄存器的使用规程、数据站的使用规则、参数的传递规则。为了适应一些特殊的需…...

Swift 判断 A B 两个时间是不是同一天,A 是不是 B 的昨天

1. 今天要做这个效果&#xff08;在时间旁边显示今天&#xff0c;昨天&#xff09; 2. Preview 3. Code: // 添加 今天 昨天 func show_today_yesterday(d: Date Date()) -> String {let calendar Calendar.currentlet today: Date Date()if calendar.isDate(today, inS…...

华为OD 高效的任务规划(200分)【java】A卷+B卷

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…...

使用VGG框架实现从二分类到多分类

一.数据集的准备 与之前的不同&#xff0c;这一次我们不使用开源数据集&#xff0c;而是自己来制作数据集。重点需要解决的问题是对数据进行预处理&#xff0c;如每一个图片的大小均不同&#xff0c;需要进行resize&#xff0c;还需要对每一张图片打标签等操作。 数据集文件 …...

Ubuntu服务器配置qq邮箱发送信息

效果&#xff1a; 此处设置的是自己给自己发送&#xff0c;配合linux的cron实现定时触发发送事件的效果 实现过程&#xff1a; 安装邮箱客户端Postfix sudo apt-get install postfix配置Postfix&#xff1a;编辑Postfix的主要配置文件 /etc/postfix/main.cf&#xff0c;并在…...

HTML读书笔记

HTML的读书笔记 概述 Jack 2023.10.23 参考网站&#xff1a; w3school 在线教程 HTML 头部 | 菜鸟教程 本教程已教你如何使用 HTML 创建站点。 HTML 是一种在 Web 上使用的通用标记语言&#xff08;并不是类似Python一样的编程语言&#xff09;。HTML 允许你格式化文本&…...

初识Java

一、Java语言概述 1.1 Java是什么 Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义 不仅如此&#xff0c;Java还是一个有一系列计算机软件和规范形成的技术体系&#xff0c;这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境&a…...

bootstrap.properties中配置Nacos

bootstrap.properties用于在Spring Boot应用程序启动阶段加载外部配置 优先级高&#xff1a;在应用程序启动时首先加载&#xff0c;用于配置应用程序的基础设置&#xff0c;如配置数据源、日志、配置服务器 外部配置&#xff1a;加载外部配置源&#xff08;如远程配置服务器&a…...

【CVPR 2023】Diffusion Models高分辨率长视频生成 Align your Latents

Diffusion Models专栏文章汇总:入门与实战 前言:CVPR 2023年的工作《Align your Latents: High-Resolution Video Synthesis with Latent Diffusion Models》实现了高帧率高分辨率长视频生成,并在保持时间一致性上做了很多工作。这篇博客详细解读一下背后的原理,并总结一下…...

[Linux 基础] make、Makefile自动化构建代码工具

文章目录 1、make与Makefile是什么2、为什么要有make与Makefile3、怎么实现一个Makefile文件3.1 如何编写Makefile文件3.1.1 依赖关系3.1.2 依赖方法 3.2 如何清理项目3.2.1 如何编写3.2.2 clean详解 3.3 make的使用3.4 原理3.4.1 查看文件修改时间 1、make与Makefile是什么 m…...

vue3结合Cesium加载倾斜摄影3dtiles

这篇文章主要是为了记录加载3dtiles时模型与地形有时候存在一些高度上的差异&#xff0c;为此将解决方法做一个记录&#xff0c;便于其他读者使用。 加载倾斜摄影3dtitle //加载倾斜摄影图像 function init3Dtiles() {const tileSet new Cesium3DTileset({url: "http://1…...

面对DDoS和APT攻击,我们该如何有效防御?

关于DDoS&#xff08;Distributed Denial of Service&#xff09;分布式拒绝服务攻击&#xff0c;是指攻击者通过技术手段&#xff0c;在很短的时间内对目标攻击网站发出大量请求&#xff0c;极大地消耗相关网站的主机资源&#xff0c;导致其无法正常服务。 打个比方来说&#…...

【前端学习】—Vue生命周期(十七)

【前端学习】—Vue生命周期&#xff08;十七&#xff09; 一、Vue生命周期 二、Vue父子组件生命周期调用顺序 三、Vue中在哪个生命周期内调用异步请求...

ant的Path-like结构

ant可以使用path和classpath结构指明路径。path和classpath可以包含内嵌的元素&#xff0c;类似下面的通用形式&#xff1a; <classpath><pathelement path"${classpath}"/><pathelement location"lib/helper.jar"/> </classpath>…...

Java设计模式之组合模式

比如在实现一个文件管理系统时&#xff0c;对于客户端来说&#xff0c;如果需要区分文件与文件夹的使用&#xff0c;会比较麻烦&#xff0c;使用组合模式可以在使用不同对象时使用方法保持一致性。 定义 又名部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对…...

【CTFshow-pwn系列】03_栈溢出【pwn 062】详解:受限缓冲区下的极简 Shellcode 注入与利用实战

本文仅用于技术研究&#xff0c;禁止用于非法用途。 Author: 枷锁 在上一关&#xff08;pwn 061&#xff09;中&#xff0c;我们利用程序主动泄露的栈基址&#xff0c;通过 gets 函数毫无限制地在内存中挥洒 Payload。但 CTF 的竞技场绝不会永远如此慷慨。 来到 PWN 062&#x…...

ArcGIS JS 基础教程(1):地图初始化(含AMD/ESM两种引入方式)

ArcGIS JS 系列基础教程&#xff08;100个项目常用热门功能&#xff09; 一、地图基础操作 1. ArcGIS JS 基础教程&#xff08;1&#xff09;&#xff1a;地图初始化&#xff08;含AMD/ESM两种引入方式&#xff09; 功能介绍&#xff1a;ArcGIS JS 开发的基础&#xff0c;实…...

AI原生不是选修课:SITS2026标准下,为什么83%的企业在Q3前必须完成架构层重构?

第一章&#xff1a;企业AI原生转型&#xff1a;SITS2026实战攻略 2026奇点智能技术大会(https://ml-summit.org) 企业AI原生转型已从战略构想进入规模化落地阶段。SITS2026&#xff08;Smart Intelligent Transformation Summit 2026&#xff09;提出“三阶跃迁”实践框架&…...

AFArray:Arduino嵌入式平台的零堆内存动态数组模板库

1. AFArray&#xff1a;面向嵌入式Arduino平台的模板化动态数组抽象数据类型AFArray 是专为 Arduino 生态设计的轻量级、模板化&#xff08;Template-based&#xff09;数组抽象数据类型&#xff08;ADT&#xff09;&#xff0c;其核心目标是在资源受限的微控制器平台上提供接近…...

R 4.5中DESeq2用于微生物组?:权威验证——3篇Nature Microbiology复现实验揭示其在低丰度菌群中的FDR失控风险

第一章&#xff1a;R 4.5中DESeq2用于微生物组分析的范式跃迁R 4.5版本对S4对象系统、并行计算支持及Bioconductor 3.19生态的深度整合&#xff0c;显著重塑了DESeq2在微生物组研究中的应用逻辑。传统上依赖OTU表与稀疏归一化&#xff08;如CSS&#xff09;的流程&#xff0c;正…...

Open Claw 接入电商 API 接口,5 分钟实现全自动比价监控(附完整源码)

做电商、做比价工具、做代购选品的朋友都懂&#xff1a;手动查价慢、易漏价、跨平台对比难&#xff0c;爬虫还容易被反爬封 IP。今天给大家带来一套零爬虫、纯接口、稳定不掉线的方案&#xff1a;用 Open Claw 快速接入电商商品详情 API&#xff0c;实现实时价格抓取 跨平台比…...

深入解析C99中函数隐式声明无效警告的根源与解决方案

1. 为什么C99标准对函数隐式声明如此严格&#xff1f; 我第一次在嵌入式项目里遇到这个警告时&#xff0c;整个人都是懵的。当时正在调试STM32的定时器初始化代码&#xff0c;编译时突然蹦出"Warning: implicit declaration of function TIM2_Int_Init is invalid in C99&…...

基于STM32与物联网平台的智能外卖柜系统开发实战

1. 项目背景与需求分析 最近两年&#xff0c;外卖柜突然成了写字楼和社区的标配。作为嵌入式开发者&#xff0c;我注意到传统外卖柜存在几个痛点&#xff1a;取件流程繁琐&#xff08;得输一长串密码&#xff09;、安全性存疑&#xff08;密码容易被偷看&#xff09;、管理不便…...

我不是狐狸,我是那Harness Engineering律

Julia&#xff08;julialang.org&#xff09;由Stefan Karpinski、Jeff Bezanson等在2009年创建&#xff0c;目标是融合Python的易用性、C的高性能、R的统计能力、Matlab的科学计算生态。 其核心设计哲学是&#xff1a; 高性能&#xff1a;编译型语言&#xff08;JIT&#xff0…...

Redis持久化:从AOF到RDB,如何实现数据不丢失?谑

Qt是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本笔记将重点介绍QSpinBox数值微调组件的常用方法及灵活应用。…...