数独终结者,能够完成数独,有源代码Rev4

Sudoku_Terminater_Rev4

数独终结者Rev 6版本
https://mp.csdn.net/mdeditor/87901247#

PS有些数独可能因为限制条件等问题,不存在唯一解,这个函数目前没有考虑这些情况,后继版本将会出针对多解存在的数独

时间仓促,没有给好输入数独函数,各位大佬就自己改 int a[9][9]吧

发现了自己N多个小错误,最终完成了能够解出存在唯一解的数独
以下为代码

#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 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 *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++) // c
			*(*ppc + i) = 1;

		for (i = 0; i < 729; i++) //maybe_a
			*(*ppa_m + i) = 1;

		for (i = 0; i < 81; i++) //cal_c
			*(*ppc_c + i) = 0;

		//这里的主要思路是行列和九宫格,分别将已有的数字标记为0
		for (i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				if (a[i][j] != 0)
				{
					//行
					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] = 0;
					}
					else if (i < 3 && j > 2 && j < 6)
					{
						c[2][1][a[i][j] - 1] = 0;
					}

					else if (i < 3 && j > 5)
					{
						c[2][2][a[i][j] - 1] = 0;
					}

					else if (i > 2 && i < 6 && j < 3)
					{
						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 > 2 && i < 6 && j > 5)
					{
						c[2][5][a[i][j] - 1] = 0;
					}

					else if (i > 5 && j < 3)
					{
						c[2][6][a[i][j] - 1] = 0;
					}

					else if (i > 5 && j > 2 && j < 6)
					{
						c[2][7][a[i][j] - 1] = 0;
					}
					else if (i > 5 && j > 5)
					{
						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[1][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 < 3 && j > 2 && j < 6 && c[2][1][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i < 3 && j > 5 && c[2][2][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i > 2 && i < 6 && j < 3 && c[2][3][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i > 2 && i < 6 && j > 2 && j < 6 && c[2][4][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i > 2 && i < 6 && j > 5 && c[2][5][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i > 5 && j < 3 && c[2][6][k] == 0)
					{
						maybe_a[i][j][k] = 0;
					}

					else if (i > 5 && j > 2 && j < 6 && 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 && a[i][j] == 0)
				{
					for (k = 0; k < 9; k++)
					{
						if (maybe_a[i][j][k] != 0)
						{
							a[i][j] = k + 1;
						}
					}
				}
			}
		}

		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";
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值