数独问题

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

一、问题描述

数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个粗线宫内的数字均含1-9,并且不重复。

输入:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出:

完整的9X9盘面数组

输入描述:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:

完整的9X9盘面数组

输入例子:

0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1

输出例子:

5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1

二、问题解决

如果采用人工填写数独的方式,过程会很复杂,即,需要判断是否能依靠某一行、某一列或者某一个九宫格能推断出某个数字,或者能否通过同一行和同一列的九宫格推断出该数字,即便这样依然有可能一个位置可能存在多个解。因此按人工填写数独的方式显然不适合机器来解决这个问题。机器更适合暴力求解,这里我们采用回溯法来解决该问题,每个为0的位置都有九种可能性,1-9,我们依次考虑填写这些数字是否满足约束条件(同一行同一列同一个九宫格不能出现相同数字),满足则继续深度搜索解,不满足则回溯。

代码:

#include <iostream>
using namespace std;

bool is_writen(int **sudo, int v, int k)
{
    for(int i = 0; i < 9; i++)
    {
        if(i != (v%9) && sudo[v/9][i] == k)
            return false;
    }
    for(int i = 0; i < 9; i++)
    {
        if(i != (v/9) && sudo[i][v%9] == k)
            return false;
    }
    int a = v/9, b = v%9;
    for(int i = 0; i < 3*3; i++)
    {
        if(!(((a/3*3 + i/3) == a) && ((b/3*3 + i%3) == b)) && sudo[a/3*3 + i/3][b/3*3 + i%3] == k)
            return false;
    }
    return true;
}

void dfs(int **sudo, int v)
{
    if(v == 81)
    {
        cout << "solution:" << endl;
        for(int i = 0; i < 9*9; i++)
        {
            if(i%9 == 0)
            {
                if(i == 0)
                    cout << sudo[i/9][i%9];
                else
                    cout << "\n" << sudo[i/9][i%9];
            } else {
                cout << " " << sudo[i/9][i%9];
            }
        }
        cout << endl;
        return;
    }
    if(sudo[v/9][v%9] == 0)
    {
        for(int i = 1; i < 10; i++)
        {
            if(is_writen(sudo, v, i))
            {
                sudo[v/9][v%9] = i;
                dfs(sudo, v+1);
                sudo[v/9][v%9] = 0;
            }
        }
    } else {
        dfs(sudo, v+1);
    }
}
void test1()
{
    int **sudo = new int*[9];
    for(int i = 0; i < 9; i++)
    {
        sudo[i] = new int[9];
    }
    for(int i = 0; i < 9*9; i++)
    {
        cin >> sudo[i/9][i%9];
    }
    dfs(sudo, 0);

    for(int i = 0; i < 9; i++)
    {
        delete sudo[i];
        sudo[i] = 0;
    }
    delete [] sudo;
    sudo = 0;
}

int main()
{
    test1();
    return 0;
}

注意对于某些输入case,可能存在有多个解,这个解题思路把所有可能存在的解都输出了。例如:

存在多个解的输入示例:

0 0 8 7 1 9 2 4 5
9 0 5 2 3 4 0 8 6
0 7 4 8 0 6 1 0 3
7 0 3 0 9 2 0 0 0
5 0 0 0 0 0 0 0 0
8 6 1 4 0 3 5 2 9
4 0 0 0 2 0 0 0 8
0 0 0 0 0 0 0 7 0
1 0 7 0 6 8 0 5 0

输出:

solution:
6 3 8 7 1 9 2 4 5
9 1 5 2 3 4 7 8 6
2 7 4 8 5 6 1 9 3
7 4 3 5 9 2 8 6 1
5 9 2 6 8 1 4 3 7
8 6 1 4 7 3 5 2 9
4 5 6 3 2 7 9 1 8
3 8 9 1 4 5 6 7 2
1 2 7 9 6 8 3 5 4
solution:
6 3 8 7 1 9 2 4 5
9 1 5 2 3 4 7 8 6
2 7 4 8 5 6 1 9 3
7 4 3 5 9 2 8 6 1
5 9 2 6 8 1 4 3 7
8 6 1 4 7 3 5 2 9
4 5 6 9 2 7 3 1 8
3 8 9 1 4 5 6 7 2
1 2 7 3 6 8 9 5 4
solution:
6 3 8 7 1 9 2 4 5
9 1 5 2 3 4 7 8 6
2 7 4 8 5 6 1 9 3
7 4 3 5 9 2 8 6 1
5 9 2 6 8 1 4 3 7
8 6 1 4 7 3 5 2 9
4 5 9 3 2 7 6 1 8
3 8 6 1 4 5 9 7 2
1 2 7 9 6 8 3 5 4
ACM:搜索算法专题(4)——数独 题目来源:         HihoCoder1321   题目描述:     给定一个数独方阵,通过程序给出数独的解。 解答: ·数独:     首先给出数独规则如下:在9×9的数表中填入数字1~9,使得每一行、每一列、每一个九宫中数字1-9都恰好出现一次,如下图:       可以看到:数表中每一行、每一列、每一个九宫(由粗线分隔)中:数字1-9中的每个数字都恰好 阅读详情

相关推荐

数独算法-递归与回溯

1.概述数独(Sudoku)是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。 1)终盘数量: 数独中的数字排列千变万化,那么究竟有多少种终盘的数字组合呢? 6,670,903,752,021,072,936,960(约为6.67×10的21次方)种组合

後雪寒的专栏 2万+

Java数独游戏

Java数独游戏 好玩。

数独生成算法问题

只要在这已知的八十一格中给出一定的已知数字和解题条件,玩家自己开动脑筋运用推理,在其他的空格上分别填入数字1到9,使1到9每个数字在每一行、每一列和每一宫都只出现一次。目前,非常有效的算法,是舞蹈链算法。它实际上也是一种回溯算法,巧妙地运用了双向十字链表的数据结构,用空间换取时间,将数独求解转化为一个精确覆盖问题,用C语言实现的算法,在普通的微机上,能够在0.1ms左右对任意标准数独进行求解。//如果之前保存的数中出现了和m相同的数,就把flag标记为1并跳出循环,表示需要重新生成随机数m。

dmxpass的博客 1178

数独游戏(C++)

数独游戏很流行,这里用“位操作”实现和解决该问题,效率高。

php 数独计算器,问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字_题来了...

这题答案不唯一的。系统给的答案:我的代码测出的答案:代码如下:#include using namespace std;bool sign = false;int num[9][9];void Output(){for (int i = 0; i < 9; i++){for (int j = 0; j < 8; j++)cout << num[i][j] << ...

weixin_39989033的博客 408

【华为机试真题详解JAVA实现】—Sudoku

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足。包含已知数字的9X9盘面数组[空缺位以数字0表示]数据范围:输入一个 9*9 的矩阵。的数字均含1-9,并且不重复。完整的9X9盘面数组。

猿小白的博客 745

*44 数独

题目描述 问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个粗线宫内的数字均含1-9,并且不重复。 输入: 包含已知数字的9X9盘面数组[空缺位以数字0表示] 输出: 完整的9X9盘面数组 输入描述: 包含已知数字的9X9盘面数组[空缺位以数字0表示] 输出描述: 完整的9X9盘面数组 示例1 输...

wenlyq的博客 631

华为机试: HJ44 Sudoku 数独填写

二维数组之数独

jianghang222的博客 1433

算法专题】数独问题详解

数独问题详解 1. 概述 根据百度百科的描述:数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个九宫格内的数字均含1-9,不重复。 下面给出数独问题的不同解法,从最简单的暴力开始,然后使用二进制进行优化,最后采用Dancing Links进行优化。 下面给出三个题目: 第一个题目使用最暴力的解法; 第二个题目使用二进制优化; 最后一个题目使用两种优化方式求

weixin_42638946的博客 6908

数独的生成算法和解题算法

github项目地址:https://github.com/Xcodingman/sudo.git配置环境:windows10 vs2013打开工程文件,运行相对应的cpp文件即可1.数独解题与出题算法一、基于递归回溯法的数独解题算法思路:众所周知,数独一般的解法需要用到很多次的推导,对各行各列各个九宫格进行排查,删选候选数后挑选候选数最少的去填。仿照这样的思想,我们用C++模拟这样的思路去解一个...

Xcodingman的博客 2万+

经典算法实战:回溯法解数独问题

本文介绍了使用回溯算法解决数独问题的经典实现方法。通过递归尝试1-9数字填充空格,结合有效性检查(行、列、3×3宫格不重复)来寻找合法解。

✨ 欢迎来到【Seal ^_^ 的CSDN博客】!✨ 1万+

回溯算法——数独问题

回溯算法的思想:每到一个十字路口A,就选择一条路走a,如果a走不通,则回到十字路口A,选择其他bcd之一,进行走。若依然走不通,则退回到A之前的十字路口,重复上面的操作。 利用回溯算法解决的经典问题数独、八皇后、0-1背包、图的着色、旅行商问题、全排列等等。 数独问题 // 此方法有点问题,结果不对,稍后修改。 #include<iostream> using namespa...

CSDN的博客 1789

【C语言】求解数独数独的解的个数 多解数独算法

解决多解数独,搜索问题

GMfengyi的博客 2105

数独问题——DLX算法

如果还没有看过DLX算法请点这里~ 题目传送门 回想一下精确覆盖问题,它的要求是每一列恰好有一个1,那么我们可以考虑将每一列作为一个限制条件,那么将数独的限制条件套进去即可。 考虑数独的限制条件: 每一个空只能填一个数(这不是废话吗。。) 每一行中不能出现重复的数字,而且只能填1~9 每一列中不能出现重复的数字,而且只能填1~9 每一个宫中不能出现重复的数字,而且只能填1~9 这样看好像不是很...

a_forever_dream的博客 1232

盘点数独终盘生成算法

数独难玩,那设置数独题目容易吗?为了讲解方便,先给数独的九宫格下一个定义,如下图所示,将数独分为9个九宫格,从上到下,从左到右依次编号1-9。将数独81个小格子定义为一个二维数组array[9][9]。如果对于数独的玩法还不了解的,那么本文并不适合你,请先移步数独百度百科了解一下数独游戏的规则。 如要构思一个生成数独题目的程序,应该从哪里入手呢?这里有两种方案:方案一,提前设置好数独库,将题...

哆啦A瑶的博客 7767

Matlab和python详解数独谜题问题

数独是一种流行的逻辑推理游戏,玩家需要将数字填入一个9x9的网格,使得每行、每列和每个3x3的子网格中都包含1-9的数字,且每个数字只出现一次。数独谜题的目标是填充缺失的数字,使得满足上述条件。整数规划是一种求解数学问题的方法,可以将数独问题转化为整数规划问题,从而通过数学模型求解。

左手の明天的博客 2007

数独问题】递归+回溯算法求解数独问题

数独是一款填充数字类的游戏,一个数独必须满足如下游戏规则:常见的数独是一个由9个3x3的九宫格组成的,总共有81个小单元格,每个单元格里面通过填充数字1到9,使得整个数独满足其规则,那么这个数独就是一个有效的数独的解。上面就是一个待完成的数独,一个数独可能没有解,也可能具有多个解,例如上面的数独其中一个解就可以如下所示: 下面介绍一下求解数独需要使用到的算法思想,即:递归和回溯算法。在解数独的过程里面,我们需要向每一个没有填充数字的单元格中,依次填充数字1到9,判断是否能够使得当前单元格所在行、列、3x..

✅ Java 开发工程师 899

数独系列算法

本文探讨了数独问题的两种核心算法:验证数独有效性和求解数独。验证数独有效性采用哈希表技术,通过三个数组记录行、列和3×3子网格的数字分布,实现O(1)时间复杂度的快速验证。解数独则运用回溯算法,在满足数独规则的前提下尝试填充数字,通过DFS递归和剪枝策略有效降低复杂度。两种算法分别体现了约束验证和搜索优化的经典思想,其方法论可推广至八皇后等约束满足问题。文章详细解析了两种算法的实现逻辑、复杂度分析和应用场景差异,为处理类似问题提供了算法范式。

nplplus的博客 1281

舞蹈链算法数独求解

舞蹈链算法数独求解 舞蹈链算法 舞蹈链算法用于求解精确覆盖问题 。 精确覆盖问题可以理解为如下问题: 给定一个01矩阵,寻找一个行的集合,使得集合中的列恰好满足每一列包含一个1。

duanhy的专栏 5812
上一篇: 回溯法及其应用
下一篇: [编程题]带括号的四则运算
na_beginning
博客等级 码龄12年 82粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值