• 数独生成算法


    算法:

    1. 随机填充中间的九宫格

    2. 通过交换行、列,填充中间的九宫格的上、下、左、右四个九宫格

    3. 同样方式填充四个角上的九宫格

    4. 根据难度随机挖去数

    C++源代码如下:

    #include <ctime>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
     
    using namespace std;
     
    const int N = 9;
    vector<int> src;
    int table[N][N];
     
    void ouput()
    {
        for (int i = 0; i < 9; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                cout << table[i][j] << "  ";
            }
            cout << endl;
        }
    }
     
    // 初始化中间的九宫格
    void centerInit()
    {
        for (int i = 0; i < N; ++i)
            src.push_back(i + 1);
        random_shuffle(src.begin(), src.end()); // 随机化序列
     
        int k = 0;
        for (int i = 3; i < 6; ++i)
            for (int j = 3; j < 6; ++j)
                table[i][j] = src[k++];
    }
     
    // 由中间的九宫格交叉变换,初始化上下左右四个九宫格
    void crossInit()
    {
        for (int i = 3; i < 6; ++i)
        {
            int l = 0;
            for (int j = 3; j < 6; ++j)
            {
                if (i == 3)
                {
                    table[i + 1][l] = table[i][j];
                    table[i + 2][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 4)
                {
                    table[i + 1][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 5)
                {
                    table[i - 2][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
            }
        }
        for (int j = 3; j < 6; ++j)
        {
            int l = 0;
            for (int i = 3; i < 6; ++i)
            {
                if (j == 3)
                {
                    table[l][j + 1] = table[i][j];
                    table[l + 6][j + 2] = table[i][j];
                    ++l;
                }
                else if (j == 4)
                {
                    table[l][j + 1] = table[i][j];
                    table[l + 6][j - 1] = table[i][j];
                    ++l;
                }
                else if (j == 5)
                {
                    table[l][j - 2] = table[i][j];
                    table[l + 6][j - 1] = table[i][j];
                    ++l;
                }
            }
        }
    }
     
    // 初始化四个角上的四个九宫格
    void cornerInit()
    {
        for (int i = 0; i < 3; ++i)
        {
            int l = 0;
            for (int j = 3; j < 6; ++j)
            {
                if (i == 0)
                {
                    table[i + 1][l] = table[i][j];
                    table[i + 2][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 1)
                {
                    table[i + 1][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 2)
                {
                    table[i - 2][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
            }
        }
        for (int i = 6; i < 9; ++i)
        {
            int l = 0;
            for (int j = 3; j < 6; ++j)
            {
                if (i == 6)
                {
                    table[i + 1][l] = table[i][j];
                    table[i + 2][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 7)
                {
                    table[i + 1][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
                else if (i == 8)
                {
                    table[i - 2][l] = table[i][j];
                    table[i - 1][l + 6] = table[i][j];
                    ++l;
                }
            }
        }
    }
     
    // 根据设定的难度随机挖数
    void generateSudoku(int difficulty)
    {
        difficulty *= 20;
        while (difficulty--)
        {
            table[rand() % 9][rand() % 9] = 0;
        }
    }
     
    // 初始化数独
    // 先随机生成中间的九宫格,再通过交叉生成上下左右四个九宫格,
    // 最后通过交叉生成四个角上的九宫格 /* 交叉顺序如下: 9 7 8 3 1 2 6 4 5 3 1 2 6 4 5 9 7 8 6 4 5 9 7 8 3 1 2 7 8 9 1 2 3 4 5 6 1 2 3 4 5 6 7 8 9 4 5 6 7 8 9 1 2 3 8 9 7 2 3 1 5 6 4 2 3 1 5 6 4 8 9 7 5 6 4 8 9 7 2 3 1 */ void init(int difficulty) { srand(time(NULL)); memset(table, 0, sizeof(table)); centerInit(); crossInit(); cornerInit(); generateSudoku(difficulty); } int main() { int d; while (true) { cout << "Please select the difficulty(1~4), input 0 to exit: "; cin >> d; if (d == 0) { break; } init(d); ouput(); } return 0; }
  • 相关阅读:
    谷歌插件开发(实现CSDN快速登陆)
    uva216 c++回溯法
    基于Linux的owncloud搭建
    Android常用代码集合
    详谈 php定时器
    Codeforces 278C Learning Languages(并查集)
    WPF中的快捷键(累积中)
    学从难出学,用从易处用
    面向对象的一种简单理解(贴标签)
    WPF与Winform中的不同(1)
  • 原文地址:https://www.cnblogs.com/qwertWZ/p/2669144.html
Copyright © 2020-2023  润新知