AcWing 166. 数独(DFS + 剪枝优化 + lowbit函数 + 状态压缩)

news2024/11/15 12:49:50

AcWing 166. 数独(DFS + 剪枝优化 + lowbit函数 + 状态压缩)

  • 一、题目
  • 二、分析
    • 1、状态压缩
    • 2、lowbit函数
      • (1)函数作用
      • (2)函数实现
    • 3、DFS思路
    • 4、剪枝优化
  • 三、代码

一、题目

在这里插入图片描述

二、分析

1、状态压缩

在这里插入图片描述

那么如果针对某一个格子而言,我们需要看一看这个格子所在的九宫格,行和列。如果这三种情况下都合法的数字,我们就可以填写。

既然需要三种情况都满足的话,我们就需要看一看这三种请况下所形成的数字中,在对应的位置上,是否是1。

只有三种情况下该位都是1的时候,这一位所代表的数字才有可能填写在该格子上。

此时,我们就可以通过一个式子: A & B & C A \& B \& C A&B&C 表示。

2、lowbit函数

(1)函数作用

这个函数的作用是求出一个数的二进制表示中,从右向左数的第一个1。

(2)函数实现

int lowbit(int x)
{
	return x & (-x);
}

比如:
在这里插入图片描述

3、DFS思路

DFS的整体思路其实是比较简单的,但是优化起来可能比较麻烦。
整体思路的话,其实就是去枚举每一个需要我们填写的格子可能填写的数字,然后依次向后枚举,直到出现答案。但是这个时间复杂度是非常的恐怖的。

那么我们该如何优化呢?

4、剪枝优化

我们知道对于一棵树而言,它靠近根节点的点,如果子树越多的话,那么整棵树的点就会很多。那么为了减少节点的个数,我们就需要让靠近跟节点的点的子树比较少。那么放到这道题中,就是说我们需要先去枚举那些可填写的合法数字比较少的格子。

这样的话,我们就能对DFS进行一定的优化。

那么在判断一个格子上所填数字是否合法的时候,我们需要去看横行,竖行,九宫格。那么加起来就是27次询问。还是比较低效的,但是根据我们刚刚状态压缩,我们只需要一个式子即可。

这也是其中的一个优化。

三、代码

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 9;
int row[N], col[N], ones[1 << N], cell[3][3];
char str[100];
int ma[1 << N];
int lowbit(int x)
{
	return x & -x;
}

int get(int x, int y)
{
	return row[x] & col[y] & cell[x / 3][y / 3];
}

void init()
{
	for(int i = 0; i < N; i ++ )
		row[i] = col[i] = (1 << N) - 1;

	for(int i = 0; i < 3; i ++ )
		for(int j = 0; j < 3; j ++ )
			cell[i][j] = (1 << N) - 1;
}

void draw(int x, int y, int nums, bool flag)
{
	if(flag)
		str[x * N + y] = '1' + nums;
	else
		str[x * N + y] = '.';
	int v = 1 << nums;
	
	if(!flag)v = -v;

	row[x] -= v;
	col[y] -= v;
	cell[x / 3][y / 3] -= v;
}

bool dfs(int cnt)
{
	if(!cnt)return true;

	int minv = INF;
	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(i, j);
				//看看能写几个数,我们从情况小的开始枚举,目的是优化。
				if(ones[state] < minv)
				{
					minv = ones[state];
					x = i, y = j;
				}
			}	
		}
	}
	int state = get(x, y);
	for(int i = state; i ; i -= lowbit(i))
	{
		//枚举当前所有可以写的数字
		int t = ma[lowbit(i)];
		//在该位补上合适的数字,并更新行,列,九宫格的状态
		draw(x, y, t, true);
		if(dfs(cnt - 1))return true;
		//复原
		draw(x, y, t, false);
	} 
	return false;
}

void solve()
{
	for(int i = 0; i < N; i ++ )ma[1 << i] = i;//记录1 << i代表的是哪个数字
	for(int i = 0; i < 1 << N; i ++ )
		for(int j = 0; j < N; j ++ )
			ones[i] += i >> j & 1;//记录二进制数字中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] != '.')
				{
					int t = str[k] - '1';
					draw(i, j, t, true);
				}
				else
					cnt ++;
			}
		dfs(cnt);
	    cout << str << endl;	
	}

}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();	
}

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

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

相关文章

情人节专场即将到来,各大平台各显神通

一年一度的情人节即将到来&#xff0c;情人节除了有情侣、恋人之间表达爱意或者追求浪漫之外&#xff0c;也有很多人想要购买一些特殊的礼物送给自己的爱人或者亲人。对于跨境电商而言&#xff0c;这个时段往往能更好的将品牌与社交媒体上的目标客户建立起联系&#xff0c;同时…

【青训营】分布式定时任务简述

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天 分布式定时任务简述 定义 定时任务是指系统为了自动完成特定任务&#xff0c;实时、延时、周期性完成任务调度的过程。分布式定时任务是把分散的、可靠性差的定时任务纳入统一平台&#xff0c;并且实现集群管理调度和…

OpenCV-PyQT项目实战(6)项目案例02滚动条应用

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列&#xff0c;持续更新中 OpenCV-PyQT项目实战&#xff08;1&#xff09;安装与环境配置 OpenCV-PyQT项目实战&#xff08;2&#xff09;QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战&#xff08;3&#xff09;信号与槽机制 …

JumpServer开源堡垒机v3.0版本设计重点解读

编者注&#xff1a;在1月17日的JumpServer开源堡垒机v3.0预发布恳谈会直播中&#xff0c;JumpServer创始人广宏伟与大家分享了JumpServer v3.0版本的设计思路与功能亮点。在v3.0版本正式发布之前&#xff0c;JumpServer开源项目组基于此次直播内容为大家整理总结了JumpServer v…

C++11可变模板参数

C11可变模板参数一、简介二、语法三、可变模版参数函数3.1、递归函数方式展开参数包3.2、逗号表达式展开参数包一、简介 C11的新特性–可变模版参数&#xff08;variadic templates&#xff09;是C11新增的最强大的特性之一&#xff0c;它对参数进行了高度泛化&#xff0c;它能…

STM32单片机红外遥控

红外遥控接口电路STM32单片机红外遥控程序源代码#include "sys.h"#define LED_RED PBout(12) //红色发光二极管控制管脚初始化PB12#define LED_GREEN PBout(13) //绿色发光二极管控制管脚初始化PB13#define LED_YELLOW PBout(14) //黄色发光二极管控制管脚初始化PB14…

反射,枚举,lambda表达式

目录 1、反射 1.1 基本概念 1.2 反射相关的类 1.3 创建 Class 对象 1.4 反射的使用 1.4.1 通过反射创建对象&#xff1a; 1.4.2 获取私有的构造方法 1.4.3 获取私有的成员变量 1.4.4 获取私有的方法 1.5 总结 2、枚举 2.1 认识枚举 2.2 使用枚举 2.3 枚举与反射…

第4章 流程控制-if-else,Switch,For循环(循环守卫,循环步长,倒叙打印),While循环,多重循环...

第 4 章 流程控制-if-else,Switch,For循环(循环守卫&#xff0c;循环步长&#xff0c;倒叙打印)&#xff0c;While循环&#xff0c;多重循环 4.1 分支控制 if-else 让程序有选择的的执行&#xff0c;分支控制有三种&#xff1a;单分支、双分支、多分支 4.1.1 单分支 1)基本语法…

Leetcode-每日一题1234. 替换子串得到平衡字符串(滑动窗口 + 哈希表)

题目链接&#xff1a;https://leetcode.cn/problems/replace-the-substring-for-balanced-string/description/ 思路 题目意思 这题意思是一个只含有[Q, W, E, R] 四个字符的字符串s且长度一定是 4的倍数&#xff0c; 需要你通过替换子串&#xff0c;使他变成一个「平衡字符…

【C++设计模式】学习笔记(6):Bridge 桥模式

目录 简介动机(Motivation)模式定义结构(Structure)要点总结笔记结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金…

【C++设计模式】学习笔记(2):模式分类与模版方法 Template Method

目录 简介模式分类GOF-23 模式分类从封装变化角度对模式分类重构获得模式 Refactoring to Patterns重构关键技法“组件协作”模式Template Method 模式动机(Motivation)结构化软件设计流程面向对象软件设计流程早绑定与晚绑定模式的定义结构(Structure)要点总结结语简介 He…

Unity(一)--通过简单例子了解属性、脚本等基础操作

目录新建工程保存视图创建游戏对象调整场景视图角度添加物理运动组件更换材质更改颜色添加脚本点击向上跳跃变色旋转UGUI的使用修改文字内容新建工程 ps:最好不使用中文文件路径及名称&#xff0c;可能会报错。 保存视图 进工程后&#xff0c;此时只有空文件夹&#xff0c;可…

《痞子衡嵌入式半月刊》 第 71 期

痞子衡嵌入式半月刊&#xff1a; 第 71 期 这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻&#xff0c;农历年分二十四节气&#xff0c;希望在每个交节之日准时发布一期。 本期刊是开源项目(GitHub: JayHeng/pzh-mcu-bi-weekly)&#xff0c;欢迎提交 issue&#xff0c…

新手做跨境电商,选对平台很重要

据数据统计&#xff0c;我国跨境电商早在2013年&#xff0c;发展态势就十分迅猛&#xff0c;交易规模达到2.7万亿元&#xff1b;而到2015年&#xff0c;仅仅两年时间&#xff0c;交易规模就突破到5万亿元&#xff1b;再过两年&#xff0c;2017年跨境电商交易规模增长到7.6万亿元…

okcc呼叫中心怎样搭建?

随着企业对服务逐渐重视&#xff0c;开始意识到呼叫中心作为客户服务水平和沟通效率的基本平台&#xff0c;并且有越来越多的企业开始利用呼叫中心外呼方式销售自己的产品。在此背景下&#xff0c;很多企业&#xff0c;无论规模大小&#xff0c;都有建立自己呼叫中心的想法。 …

docker的资源控制管理——Cgroups

引言&#xff1a;docker 使用cgrqup控制资源&#xff0c;K8S 里面也有limit&#xff08;使用上限&#xff09;docker通过cgroup来控制容器使用的资源配额&#xff0c;包括CPU、内存、磁盘三大方面&#xff0c;基本覆盖了常见的资源配额和使用量控制。Cgroup 是 Control group 的…

Jboss EAP 7.4.8配置jacoco 端口无法开启 启动报错

项目场景&#xff1a; servers: Jboss EAP 7.4.8 JDK: JDK17 jacoco: 测试jacoco-0.7.9 jacoco-0.8.5 jacoco-0.8.8 问题描述 问题1: Jboss 启动 VM arguments追加, 如下启动参数&#xff1a; -javaagent:F:\CoverageReport\jacoco-0.7.9\lib\jacocoagent.jarincludes*,o…

别具一格,原创唯美浪漫情人节表白专辑,(复制就可用)(html5,css3,svg)表白爱心代码(1)

别具一格&#xff0c;原创唯美浪漫情人节表白专辑&#xff0c; (复制就可用)&#xff08;html5,css3,svg)表白爱心代码(1) 一、 前言 回眸之间&#xff0c;丰盈了岁月&#xff0c;涟漪了思绪&#xff0c;轻轻落笔&#xff0c;不写伤痕&#xff0c;不写仇怨&#xff0c;只写岁月…

反光板导航SLAM(三)反光柱导航开发与实验

在上一章中简单了解了VEnus算法对于反光柱导航的基本思路。其主要分为了高反点提取、高反点聚类查找中心、高反点与已知反光柱位姿匹配以及调用ceres库进行位姿优化等步骤。然后在这个算法的基础上&#xff0c;再进行一定的开发达到一个比较稳定且可视化的版本。 使用&#xff…

json对象和formData相互转换

前言 大家都知道&#xff0c;前端在和后台进行交互联调时&#xff0c;肯定避免不了要传递参数&#xff0c;一般情况下&#xff0c;params 在 get 请求中使用&#xff0c;而 post 请求下&#xff0c;我们有两种常见的传参方式&#xff1a; JSON 对象格式和 formData 格式&#x…