C++使用回溯法生成数独

数独的生成以及解答--回溯算法c++附详细代码 首先准备一个空的数独,从第一个格子开始,按照数独的规则,把1-9依次试探性的填入,如果合法,就填入.如果不合法就判断下一个数合不合法,这样,一直到把第81个格子填完,就生成了一个完整的数独,但是因为这样生成的数独是一个固定的,所以,现在我们要随机把它打乱,根据数独的特性,在同一个小九宫格中的行和行之间交换位置,列与列之间交换位置,数独依然成立,打个比方,第0行和第2行,交换位置,第0列和第2列交换位置,数独依然成立.。这样直到把所有空格都遍历完成.。 阅读详情

数独,应该不用我说明吧,是一个9*9的矩阵,矩阵里的每一个数字都是1~9中的一个。在每一行、每一列每个数字只能出现一次,另外,在每一个九宫格里每个数字也只能出现一次。

我曾经在网上看过一种“假”的数独生成法,生成的数独其实是有规律的,只要把中间的九宫生成好,那么周围的8个九宫就可以按照规律自动生成,但是这样的话便达不到“随机”的效果,于是经过苦想我想出了下面的方法:

按行生成数字。如果生成了与该行或该列相同的数字,或在这个九宫里有重复的数字,则删除刚刚生成的相同数字并且重新生成该数字。简而言之,就是先检查行,再检查列,再检查九宫,直到把这81个数字都生成出来。如果某一行出现“无解”的情况,则重新生成上一行,称之为“回溯”。

可想而知,这样的程序效率是不高的。首先的问题就是,要如何生成第一行没有重复的数字?最原始的办法就是从1~9依次随机,如果生成的数与该行某个数相同,则重新生成。但是这样的话程序效率很低,因为随机的次数会很多,比方说假设到了要生成某一行的最后一个数了,那么这个数成功生成的概率只有1/9,电脑平均要随机9次才可以生成。因此我想的方法是把每一行能够填入的数保存在一个数组avail里,并且初始化int avail[9]= {1,2,3,4,5,6,7,8,9},一旦成功生成某个数,那么就在avail里删除这个数,例如生成了3,那么就从avail里删掉'3',这样的话就可以大大的减少随机的次数。

按照这个思路,我设计了一下代码:

#include <iostream>

#include <stdlib.h>

#include <time.h>

#include <conio.h>

using namespace std;

int sudoku[9][9],avail[9]={1,2,3,4,5,6,7,8,9};//定义数独数组和可选数字数组

代码中的sudoku是用来保存数独的二维数组,avail是每一行可以填入的数字,可以知道,每当行数向下加一的时候avail就必须要重置一次。

void remove(int t[],int);//声明移除前置函数

void restore(void);//声明重置函数

void print(void);//声明打印数独函数

void init(void);//声明初始化函数

int search(int t[],int);//声明搜索下标函数

int en=9;//可选avail下标

Remove函数是用来删除t数组(也就是avail数组)里某个特定的数的,restore函数是用于重置avail数组的,print函数是用于打印数组的,init函数是用于初始化sudoku二维数组。Search函数用于查找avail数组中某个数的位置(下标),以便删除。如果这个数不存在则返回-1。整数en是可选数字的最大下标,每从avail里删除一个数,则都要有en--。

下面是函数的定义:其中srand是根据时间来随机化。

void init() //初始化

{

int x,y;

srand(time(NULL));

for (y=0;y<=8;y++)

{

for (x=0;x<=8;x++)

{

sudoku[y][x]=0;

}

}//初始化数组

}

void remove(int t[],int n) //n为下标,移除排除下标,项前移

{

int i;

for (i=n;i<=7;i++)

{

t[i]=t[i+1];

}

en--;//可选数字在原有基础上减

}

int search(int t[],int n) //n为搜索的数字,返回下标,如果没有则返回-1

{

int i;

for (i=0;i<=en-1;i++)

if (t[i]==n)

return i;

return -1;

}

void restore() //初始化en,avail

{

int i;

en=9;

for (i=0;i<=8;i++)

avail[i]=i+1;

}

void print(void)

{

int i,j;

for (i=0;i<=8;i++)

{

for (j=0;j<=8;j++)

{

cout << sudoku[i][j] << " "; 

}

cout << endl;

}

}

接下来就只有main函数了。

我的思路是每生成一个数,马上判断它的同行、同列和同九宫里有没有与之相同的数,如果有则重新生成该数,没有则从avail里删除这个数。判断同行和同列比较方便,用简单的循环就可以搞定,排除九宫则稍微复杂一点,它需要两个循环。假设有两个整型变量x和y,分别是sudoku数组的列坐标和行坐标,已知某数的是sudoku[y][x],由于在C++中两个整型数相除的结果还是整数,那么sudoku[(y/3)*3][(x/3)*3]就是该数所在的九宫的第一个数,然后进行循环便可以判断九宫了。如果是无解,则重新生成上一行。Main函数源代码如下:

int main()

{

int x=0,y=0;

int kill;//已存在的数的小标

init();

cout << "正在生成一个数独..." << endl;

for (y=0;y<=8;y++)

{

for (x=0;x<=8;x++)

{

/*思路:每将生成一个新数字的时候,重新生成avail数列*/

int i,j;

for (i=0;i<=x;i++)//排除横行

{

kill=search(avail,sudoku[y][i]);

if (kill!=-1)

remove(avail,kill);

}

for (i=0;i<=y;i++)//排除纵行

{

kill=search(avail,sudoku[i][x]);

if (kill!=-1)

remove(avail,kill);

}

for (i=0;i<=2;i++) //排除九宫

{

for (j=0;j<=2;j++)

{

kill=search(avail,sudoku[(y/3)*3+i][(x/3)*3+j]);

if (kill!=-1)

remove(avail,kill);

}

}

if (en==0 && y>0) //排除无解

{

y-=2;

break;

}

else if (en==0 && y==0)

{

init();

y=-1;

break;

}

sudoku[y][x]=avail[rand()%en];

restore();

}

restore();

}

print();//打印数独

getch();

return 0;

}

心得:尽管经过优化,这个程序运算速度仍然要靠人品。这是个纯计算问题,没有用到一些高深的知识。没有用到类,函数与函数之间的耦合性也非常的强。但是这还是需要掌握对数组的操作。该程序在VC6.0下编译通过。

 

 


[C++] 回溯法生成数独 算法思路 首先第一行肯定是1~9的一种排列,直接使用shuffle进行随机。 从第二行第一个开始,尝试填入数字,填入后依据数独规则进行可行性判断。如果可以填入该数字,则对下一格进行相同的判断。如果某一格对于任何数字的填入都违反了数独规则,则进行回溯,重新填上一格的数字。 当获得一个可行结果时,算法终止。 阅读详情

相关推荐

数独终局生成及残局求解

目录 一、项目地址 二、各模块开发时间预估 三、学习过程、解题思路 四、设计实现过程 五、程序性能分析及改进 六、代码说明 七、单源测试与代码覆盖率分析 八、各模块实际开发时间及与预期对照 九、个人总结 ...

qq_40036347的博客 1313

递归回溯生成和解决数独问题c/c++

数独 程序地址https://github.com/papicheng/blog/tree/master/%E6%95%B0%E7%8B%AC 一、游戏规则介绍: 数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。 程序介绍...

qq_24624539的博客 2275

回溯算法求解数独

自己搞得个小程序 可快速求解一般的数独题目 input采用文档 简介好用

对回溯算法的理解(以数独游戏为例,使用c++实现)

算法思想: 数独游戏的规则: 每一行都用到1、2、3、4、5、6、7、8、9位置不限; 每一列都用到1、2、3、4、5、6、7、8、9位置不限; 每3×3的格子(共九个这样的格子)都用到1、2、3、4、5、6、7、8、9位置不限。 游戏的过程就是用1、2、3、4、5、6、7、8、9填充空白,并要求满足每行、每列、每个九宫格都用到1、2、3、4、5、6、7、8、9。实现方法: 由于数...

hopegrace的博客 716

并行计算回溯法求解数独问题c++

并行计算回溯法求解数独问题c++求解,openmp

回溯法解决数独问题

命令行输入源文件与结果输出文件,空位置输入为0

回溯法解数独C++

数独游戏 数独游戏是由99共81个格子组成,其中整个网格分为33的大格子,大格子又分为3*3的小格子,给定一些格子中的数,往空白格子里面填数。规则是:只能填1-9这9个数字,而且每一行,每一列和每一大格子里一个数字只能出现一次。 输入格式:将81个字符按先下后上先左后右的顺序输为一行(未知的空白格子用‘ . ’表示),end表示结束的标志。 输出格式:每个输入数据输出为一行。 #include <bits/stdc++.h> using namespace std; string temp; c

wck__yoyo的博客 478

ADRC自抗扰控制:工程抗扰“黑科技”,附C代码实战!

自抗扰控制(ADRC)是一种革新性的强鲁棒控制策略,通过主动估计和补偿系统扰动,无需精确数学模型即可实现优异控制性能。本文详细解析ADRC三大核心组件:跟踪微分器(TD)实现指令柔化,扩张状态观测器(ESO)实时估计总扰动,非线性状态反馈(NLSEF)完成动态补偿。针对二阶系统,文章提供完整的参数设计方法和C语言实现框架,包括关键函数fhan和fal的代码实现。ADRC将复杂对象"线性化"为积分器串联系统,显著提升抗扰能力,特别适用于电机控制、飞行器姿态等存在模型不确定性和强干扰的场景。

技术工作者 1736

数独(一)

Github地址:https://github.com/cfafa2018/SudokuProject 思路: 根据题目要求,摘取出一些需要解决的问题,差不多也就是整体的解题思路。 代码分成了两大块,生成数独和解数独部分,还有一些小的函数。 (1)命令行中使用 -c和-s,识别并根据命令生成或读取相应的文件。     用ofstream和C语言里面的fopen。对于-c和-s以...

dishen9342的博客 286

Windows打印体系结构之Windows内置打印驱动程序

时间是一种很残酷的东西,它只会冲淡能够冲淡的,但也会洗尽铅华帮你留下该留下的。1.3.4、Windows内置打印驱动程序现在的Windows下的打印机驱动程序通常分为V4打印机驱动程序(V4 Printer Driver)、XPS打印机驱动程序(XPSDrv)、微软通用打印机驱动程序(Microsoft UniversalPrinter Driver)、微软PostScri...

weixin_34309435的博客 2254

5分钟搞懂MSDNet:用Transformer实现小样本语义分割的保姆级教程

本文详细介绍了MSDNet(Multi-Scale Decoder Network)如何利用Transformer架构实现小样本语义分割。通过多尺度解码器和空间Transformer解码器,MSDNet能够在仅有1-5张标注图像的情况下完成精确分割任务。文章提供了PyTorch代码实例和优化技巧,帮助开发者快速掌握这一前沿技术。

weixin_30832143的博客 506

个人项目-数独程序

1)GitHub传送门 https://github.com/MinstrelZal/Sodoku 2)PSP表格 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 1 * 60 0.5 * 60 · Estimate · 估计这个任务需要多少时间 1 * 60 0.5 * 60 ...

anranmei1023的博客 420

汽车诊断之UDS入门-0x19 0x0A服务

0x19 0x0A解析

weixin_44842720的博客 3836

软工个人项目——数独(三)

软工个人项目——数独(三) 前段时间一直在准备考试,数独项目进展比较缓慢,现在继续记录进程。本篇博客主要记录数独解决部分的设计实现和两个模块的汇总及main.cpp的实现。 Github项目地址:个人数独项目 1.Solve_Sudoku.cpp的实现 数独的解决方案有很多思路,我首先想到的是用回溯或者DFS进行解题。这里我先选用了回溯法实现,之后在性能优化阶段可以改用DFS进行对比。 回溯法实现...

dmy的博客 286

Android音频子系统分析-car_audio_configuration.xml

先附上一个例子,再逐一解释。概括来说,该文件描述了车里有哪些区域,每个区域划分了多少组,每个组包含了哪些设备,每个设备接收哪些类型的音频流。

不定时记录分享一些有用没用的东西 989

若依(RuoYi)框架从零到部署:Spring Boot+Vue权限系统完整配置指南

在Java企业级应用开发中,Spring Boot作为构建微服务和单体应用的基石,极大地简化了项目初始化和配置流程。其核心原理在于通过自动配置和起步依赖,快速整合数据访问、安全认证、缓存等常用模块,显著提升开发效率。这一技术价值在需要快速构建后台管理系统的场景中尤为突出,例如权限管理、用户角色分配等通用需求。若依(RuoYi)框架正是基于Spring Boot和Vue.js的优秀实践,它封装了RBAC权限模型、代码生成器等高频功能,提供了开箱即用的解决方案。本文聚焦于若依框架的【环境配置】与【项目部署】,通

weixin_33984032的博客 455

1.15 构造数独

(一) 用回溯法构造数独 #include <iostream> #include <cstring> #include <ctime> #include <cstdio> #include <cstdlib> using namespace std; int sudu[9][9]; void ...

aofan9566的博客 153

【数据集8】全球人口数据WorldPop详解

全球人口数据WorldPop详解

WW、forever的博客 7880

数独生成算法

挖空操作:通过随机数生成器随机选择棋盘上的一些格子,将其原本的数字置为0来实现挖空,同时可控制挖空的数量来调节谜题难度,为玩家创造不同挑战程度的数独题目。1. 采用回溯法实现数独的求解,通过递归地尝试在空白格放置数字,用 isSafe 函数判断,若某一放置导致后续无解则回溯,重新选择数字尝试,直至找到完整解或确定无解。以传统数独的规则为基础进行设计,即每行、每列以及每个3x3的子网格内都要包含1到9这九个数字且不能重复,围绕此规则来构建各个功能模块,确保生成的谜题和验证的解答都符合要求。

Ttence的博客 426

SAP GUI 经典事务在 Fiori Launchpad 中的穿越之道:原理、配置与实践指南

在许多企业的 S/4HANA 或 ECC 系统里,经典 SAP GUI 事务依旧承载着关键业务。如何把这些老将自然地嵌入到 Fiori Launchpad,让用户在统一入口里无缝切换新旧 UI,是项目中经常遇到的主题。本文结合社区博文、官方文档与实际项目经验,系统梳理这一过程的技术原理、配置步骤、性能优化以及常见坑点,并给出贴近中国读者的案例解析与改进建议。阅读完毕,你将不仅知道怎么做,还会理解。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 623

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

软件工程个人项目-数独2

设计

qq_43345144的博客 162

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

八叶一刀流·二之型·疾风数独

项目相关要求 Github 项目地址:https://github.com/zjwml4581792/Software-engineering 第一次的真软工实践作业就是这种题目,想想还有点小激动,终于又要敲代码啦。看着自己现在的编程的“纸飞机阶段”,想完成,还是等待~并心怀希望吧! 先看题目。 我是题目 度娘说:数独(百度百科) 数独(Sudoku,Crosswords)是源自18世纪瑞士...

weixin_33897722的博客 151

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

个人项目实战(数独)

个人项目实战 项目地址:https://github.com/kddll/soduku 作业地址 https://edu.cnblogs.com/campus/fzu/SoftwareEngineering2015/homework/859 Documents 项目需求 利用程序随机构造出N个已解答的数独棋盘 。 编程语言:C++ 编程IDE:推荐使用Visual Studio 2017 源...

weixin_30947043的博客 223

数独终局生成和求解

软件工程基础个人大作业 数独终局生成和求解 github项目地址https://github.com/lukal-new/new-potato/tree/sudoku 一、预计开发 Personal Soft 预估耗时(分钟) 计划 计划 计划 计划 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如...

Luke___的博客 661

软件工程个人项目-数独

软件工程个人项目-数独 一.项目的Github地址链接: https://github.com/tarxs/sudokuproject 二.psp预估耗时表格: 三.解题思路: A.如何生成数独 看到题目,首先搜索数独具体的定义。由于题目和格局有关,自然而然想到n皇后问题,继而想用回溯法求解这个题目。但是输入的规模太大了,即使剪枝也不能达到很好的时间复杂度。于是我在网上搜索了一些如何用计算机解数...

tarxsbc的博客 538
下一篇: VB.NET 构造矩阵类
Froser
博客等级 码龄17年 131粉丝 31原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值