其原名为数独终结者
但奈何我调试了很久,代码重写了三回他也是一个数独复读机。
第一次玩这个博客也时深夜,想要保住自己的头发,格式简单点,没有什么套路
顺手发下自己这个浪费计算资源的 数独终结者 V -3.0(-1.0 和 -2.0已被祭天) 版本
数独复读机
#include "pch.h"
#include <iostream>
int main()
{
int i, j, k;
std::cout << "数独终结者\n";
int maybe_a[9][9][9]; // 某个数字可能存在的值
int c[3][9][9]; // 行列九宫格 限制条件
int cal_c[9][9]; // 用于计数 当该单元格的被限制条件限制只能取1个数时,则将该数填入数独数组
int flag; //用于标记那一个数的位置
bool jud_1 = true; //用于判定是否完成了数独
bool jud_2 = true; //用于判定是否运算次数过多而毫无进展
int jud_i = 0; //计数循环次数,大于某一值认为当前算法有问题,无法解决数独问题,中断循环
int sta_a[9][9];
int a[9][9] = { {5,3,0,8,4,1,6,2,0},{9,0,0,5,0,2,8,0,0},{0,0,0,0,6,9,0,0,1},
{0,0,0,2,0,0,0,1,0},{7,5,2,1,0,0,9,8,6},{1,4,0,7,9,0,0,5,3},
{0,0,0,0,8,3,0,4,2},{4,0,1,6,2,7,3,9,5},{0,0,3,0,0,5,0,6,0} }; //初始数独
//二级指针用于快速寻址
int *pa_s;
int **ppa_s;
pa_s= &sta_a[0][0];
ppa_s = &pa_s;
int *pc;
int **ppc;
pc = &c[0][0][0];
ppc = &pc;
int *pc_c;
int **ppc_c;
pc_c = &cal_c[0][0];
ppc_c = &pc_c;
int *pa_m;
int **ppa_m;
pa_m = &maybe_a[0][0][0];
ppa_m = &pa_m;
//数独输出
for (i = 0; i < 9; i++)
{
std::cout << "数独如下";
for (j = 0; j < 9; j++)
{
std::cout << a[i][j] << " ";
}
std::cout << "\n";
}
while (jud_1&&jud_2)
{
//重新赋值
for (i = 0; i < 243; i++)
*(*ppc + i) = 1;
for (i = 0; i < 729; i++)
*(*ppa_m + i) = 1;
for (i = 0; i < 81; i++)
*(*ppc_c + i) = 0;
//这里的主要思路是行列和九宫格,分别将已有的数字标记为0
for (i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (a[i][j] != 0)
{
sta_a[i][j] = 1;
//行
c[0][i][a[i][j] - 1] = 0;
//列
c[1][j][a[i][j] - 1] = 0;
//九个九宫格
if (i < 3 && j < 3)
{
c[2][0][a[i][j] - 1];
}
else if (i < 6 && i > 2 && j < 3)
{
c[2][1][a[i][j] - 1] = 0;
}
else if (i > 5 && j < 3)
{
c[2][2][a[i][j] - 1] = 0;
}
else if (i < 3 && j > 2 && j < 6)
{
c[2][3][a[i][j] - 1] = 0;
}
else if (i < 6 && i > 2 && j > 2 && j < 6)
{
c[2][4][a[i][j] - 1] = 0;
}
else if (i > 5 && j > 2 && j < 6)
{
c[2][5][a[i][j] - 1] = 0;
}
else if (i < 3 && j > 5) {
c[2][6][a[i][j] - 1] = 0;
}
else if (i < 6 && i > 2 && j > 5)
{
c[2][7][a[i][j] - 1] = 0;
}
else
{
c[2][8][a[i][j] - 1] = 0;
}
}
}
}
// 9 9 9 判定
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
for (k = 0; k < 9; k++)
{
if (c[0][i][k] == 0)
maybe_a[i][j][k] = 0;
if (c[0][j][k] == 0)
maybe_a[i][j][k] = 0;
//九个九宫格
if (i < 3 && j < 3 && c[2][0][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i < 6 && i > 2 && j < 3 && c[2][1][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i > 5 && j < 3 && c[2][2][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i < 3 && j > 2 && j < 6 && c[2][3][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i < 6 && i > 2 && j > 2 && j < 6 && c[2][4][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i > 5 && j > 2 && j < 6 && c[2][5][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i < 3 && j > 5 && c[2][6][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i < 6 && i > 2 && j > 5 && c[2][7][k] == 0)
{
maybe_a[i][j][k] = 0;
}
else if (i > 5 && j > 5 && c[2][8][k] == 0)
{
maybe_a[i][j][k] = 0;
}
}
}
}
/* std::cout << "\n";
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
for ( k = 0; k < 9; k++)
{
std::cout << maybe_a[i][j][k] << " ";
}
std::cout << "\n";
}
}*/
//处理数独
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
for (k = 0; k < 9; k++)
{
if (maybe_a[i][j][k] != 0)
{
cal_c[i][j]++;
}
}
if (cal_c[i][j] == 1 && sta_a[i][j] == 0)
{
for ( k = 0; k < 9; k++)
{
if (maybe_a[i][j][k] != 0)
{
a[i][j] = k;
}
}
}
}
}
jud_1 = false;
for (i = 0; i < 81; i++)
{
if (a[i / 9][i % 9] == 0)
jud_1 = true;
}
jud_i++;
if (jud_i > 10000)
jud_2 = false;
}
std::cout << "结果如下\n";
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
std::cout << a[i][j] << " ";
}
std::cout << "\n\n";
}
}
相信我,他迟早有一天会是面向对象,封装好,使用指针来寻址数组,结构简单并且高效,拥有UI数独终结者
甚至可能还有多线程,并发处理,CUDA加速,虽然我也不知道并行加速能给这个程序带来什么提升
本文完