1.15 构造数独

(一)

用回溯法构造数独

#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdio>
#include <cstdlib>
using namespace std;

int sudu[9][9];

void sudu_print(int sudu[][9]) {
    for(int i = 0; i < 9; ++i) {
        for(int j = 0; j < 9; ++j) {
            cout << " " << sudu[i][j];
        }
        cout << endl;
    };
}

bool is_digital_sudu(int sudu[][9], int i, int j) {
    for(int k = 0; k < 9; ++k) {
        if(k == j) continue;
        if(sudu[i][k] == sudu[i][j]) return false;
    }
    for(int k = 0; k < 9; ++k) {
        if(k == i) continue;
        if(sudu[k][j] == sudu[i][j]) return false;
    }
    int p = i / 3;
    int q = j / 3;
    for(int m = 3 * p; m < 3 * p + 3; ++m) {
        for(int n = 3 * q; n < 3 * q + 3; ++n)
            if(m != i && n != j && sudu[m][n] == sudu[i][j]) return false;
    }
    return true;
}

int main() {
    srand(time(0));
    memset(sudu, 0, sizeof(sudu));
    for(int i = 0; i < 9; ++i) {
        int temp = rand() % 81;
        sudu[temp/9][temp%9] = i + 1;
    }
    int k = 0;
    while(1) {
        int x = k / 9;
        int y = k % 9;
        while(1) {
            sudu[x][y]++;
            if(sudu[x][y] == 10) {
                sudu[x][y] = 0;
                --k;
                break;
            }else if(is_digital_sudu(sudu, x, y)) {
                k++;
                break;
            }
        }
        if(81 == k) {
            sudu_print(sudu);
            return 0;
        }
    }
    return 0;
}

在LINUX下运行的话,先运行命令:g++ 文件名称.cpp   然后假设程序没有错误的话。那么在该文件夹以下会自己主动生成一个文件:.out。

所以这个时候继续在该文件夹下运行:

./a.out

(二)

利用书上的置换的方法,简单。

。。

时间: 2024-11-10 01:42:53

1.15 构造数独的相关文章

第1章 游戏之乐——构造数独

构造数独 1. 问题 构造一个9*9的方格矩阵,玩家要在每个方格中,分别填上1至9的任意一个数字,让整个棋盘每一列.每一行以及每一个3*3的小矩阵中的数字都不重复. 2. 求解 用转置的方法生成数独数组,代码如下: 1 package chapter1youxizhileShuDu; 2 3 import java.util.Random; 4 5 /** 6 * 用置换法生成数独矩阵 7 * @author DELL 8 * 9 */ 10 public class ShuDu { 11 pr

构造数独

编程之美有一道关于深度搜索和回溯应用的题目--构造数独: 数独的棋盘是由九九八十一个小方格组成的.玩家在每个小格子中,分别天上1至9的任意一个数字,让整个棋盘每一行,每一列,以及每一个3*3的小矩阵中的数字都不重复. 作者给两种解法: 解法一: 下面的GenerateValidMatrix()函数用经典的深度优先搜索来生成一个可行解.从(0,0)开始,对没有处理过的格子,调用GetValidValueList(coCurrent)来获得当前格子可能的取值选择,并从中取一个为当前格子的取值,接着搜

[javase学习笔记]-7.15 构造代码块

这一节我们再看一个特殊的代码块,那就是构造代码块. 这里我们简单的通过例子来说明一下: class Person { private String name; { System.out.println("Person类的第一个代码块被执行"); } Person() { System.out.println("无参数构造函数被执行"); this.name = "小宝宝"; } Person(String name) { System.out.p

编程之美之数独求解器的C++实现方法

编程之美的第一章的第15节,讲的是构造数独,一开始拿到这个问题的确没有思路, 不过看了书中的介绍之后, 发现原来这个的求解思路和N皇后问题是一致的, 但是不知道为啥,反正一开始确实没有想到这个回溯法,知道是用回溯法求解之后,问题就变得容易了很多. 这里我们不打算实现数独的构造,相反的,我们实现一个数独求解器,以后妈妈再也不用担心我的数独了. 当然求解器的思路和构造数独的思路一样,都是回溯法搜索,这里不再过多说明. 程序运行说明: 1.把待求解的数独数据放到in.txt文件中, 程序会自动读取他,

数独解法c++实现

转自http://blog.csdn.net/qq_31558353/article/details/50615760 用个小样列(据说是世界上最难的数独,10s过) //<pre code_snippet_id="1592833" snippet_file_name="blog_20160301_1_4048211" name="code" class="cpp">#include <iostream>

[ActionScript 3.0] AS向php发送二进制数据方法之——在URLRequest中构造HTTP协议发送数据

主类 HTTPSendPHP.as 1 package 2 { 3 import com.JPEGEncoder.JPGEncoder; 4 import com.fylib.httpRequest.HttpRequestBuilder; 5 import com.fylib.httpRequest.HttpRequestBuilderConsts; 6 import flash.display.Bitmap; 7 import flash.display.BitmapData; 8 impor

LinkedList

LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明. 1.链表的概念 链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和双向链表,而单向/双向链表又可以分为循环链表和非循环链表,下面简单就这四种链表进行图解说明.           1.1.单向链表 单向链表就是通过每个结点的指针指向下一个结点从而链接起来的结构,最后一个节点的next指向null.      1. 2.单向循环链表           单向循环

黑马程序员系列第二篇 多线程(2)

ASP.Net+Android+IOS开发  .Net培训.期待与您交流! (前言:本篇文章主要依据毕向东老师的课程视频整理而成,如要详细学习,请观看毕老师视频  百度网盘链接地址:http://pan.baidu.com/s/1sjQRHDz) 目录:1.线程通信--生产消费者示例(线程通信安全.等待唤醒机制)    2.停止线程.及其会出现的问题.及解决的办法    3.守护线程及几个Thread的方法                   4.工作中线程的常见写法         1.线程通

编写高质量代码:改善Java程序的151个建议(第3章:类、对象及方法___建议36~40)

建议36:使用构造代码块精简程序 什么叫做代码块(Code Block)?用大括号把多行代码封装在一起,形成一个独立的数据体,实现特定算法的代码集合即为代码块,一般来说代码快不能单独运行的,必须要有运行主体.在Java中一共有四种类型的代码块: 普通代码块:就是在方法后面使用"{}"括起来的代码片段,它不能单独运行,必须通过方法名调用执行: 静态代码块:在类中使用static修饰,并用"{}"括起来的代码片段,用于静态变量初始化或对象创建前的环境初始化. 同步代码块