递归方法暴力求解数独

#include <iostream>
#include <time.h>
#include<windows.h>

using namespace std;

void SetColor(unsigned short ForeColor=7, unsigned short BackGroundColor=0)
{
	HANDLE hCon = GetStdHandle( STD_OUTPUT_HANDLE );
	SetConsoleTextAttribute( hCon, ForeColor | BackGroundColor );
}

/*
 * 在屏幕上输出9*9方格
 * 方格的边框为白色
 * 方格中原有的数字为白色
 * 方格中用户输入的数字为红色
 */
int print(int *a, int *b)
{
	int i, j;

	cout << "┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓" ;
	cout << endl;

	for ( i = 0; i < 9; i ++ ) {
		for ( j = 0; j < 9; j ++ ) {
			if ( (a[i*9+j] == 0) && (b[i*9+j] == 0) ) {
				cout << "┃   ";
			}
			else if ( b[i*9+j] != 0 ) {
				cout << "┃ ";
				cout << b[i*9+j] << " "; 
			}
			else if ( a[i*9+j] != 0 ) {
				cout << "┃ ";
				SetColor(  4 );
				cout << a[i*9+j] << " "; 
				SetColor( 15 );
			}
		}
		cout << "┃" << endl;

		if ( i != 8 ) {
			cout << "┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫";
			cout << endl;
		}
		else {
			cout << "┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛";
			cout << endl;
		}
	}

	return 0;
}

/****************************************************
	函数名:check( int *in, int x, int y, int t)
	参    数:
					1. in	- 部分/全部求解的数独
					2. x	- 方格的横坐标
					3. y	- 方格的纵坐标
					4. t	-  要填入方格的数
	功    能: 检测将t填入方格(x,y)是否会产生冲突
					冲突则返回0,否则返回1
 ****************************************************/
int check(int *in, int x, int y, int t)
{
	int i, j, row, col;

	for ( i = 0; i < 9; i ++ )
		if ( (in[x*9+i] == t) || (in[i*9+y] == t) )
			return 0;

	row = x / 3 * 3;
	col = y / 3 * 3;
	for ( i = row; i < row+3; i ++ )
		for ( j = col; j < col+3; j ++ )
			if ( in[i*9+j] == t )
				return 0;

	return 1;
}

/****************************************************
	函数名:solve( int *in, int *sol, int n)
	参    数:
					1. in	- 部分/全部求解的数独
					2. sol - 未求解的数独
					3. n	- 待求解的方格
	功    能: 递归求解数独
 ****************************************************/
void solve(int *in, int *sol, int n)
{
	/************************************************
	 * 算法如下:
	 * 如果n为81,则 {
	 *		调用print打印答案
	 *		递归结束
	 *	}
	 * 如果当前的方格中没有数字,即为0 {
	 *		查看1-9中哪个数字k可以填入
	 *			如果可以填入,则
	 *				将当前方格置为k
	 *				调用solve(in, sol, n+1)递归
	 *		将当前方案置为0,回溯
	 *	}
	 *	否则
	 *		调用solve(in, sol, n+1)递归
	 ************************************************/
	/************************************************
	 * To Do: 按照上面的算法,实现solve函数
	 * 代码写在注释Begin和End之间
	 * !!! 一定不要修改其他代码 !!!
	 ************************************************/

	/********************* Begin *******************/
	int x,y,i;
	x=n/9;
	y=n%9;
	if(n==81)
	{
		print(in,sol);
	}
	else if(sol[n]==0)
	{
		for(i=1;i<10;i++)
		{
			if(check(in,x,y,i))
			{
				in[n]=i;
				solve(in,sol,n+1);
			}
		}
		in[n]=0;
	}
	else
	{
		solve(in,sol,n+1);
	}
	/*********************  End   *******************/

	return;
}

int main()
{
/* 题目1 */
	int a[9][9] = {
	0,0,0,0,0,1,0,0,7,
		0,0,0,0,0,9,2,3,1,
		0,2,0,0,8,0,0,5,0,
		7,6,0,0,0,0,0,0,8,
		0,0,0,2,0,4,0,0,0,
		9,0,0,0,0,0,0,1,6,
		0,7,0,0,4,0,0,6,0,
		5,3,9,8,0,0,0,0,0,
		8,0,0,9,0,0,0,0,0};

/* 题目2 */
/*int a[9][9] = {
		6,0,0,8,0,4,0,0,0,
		0,0,5,0,0,1,0,7,0,
		1,0,3,0,5,0,0,0,0,
		7,0,0,4,0,2,9,0,0,
		4,0,0,0,0,0,0,0,2,
		0,0,2,1,0,6,0,0,7,
		0,0,0,0,7,0,4,0,0,
		0,7,0,5,0,0,2,0,0,
		0,0,0,2,0,9,0,0,1
	};*/

/* 题目3 */
/*	int a[9][9] = {
		0,0,0,0,0,1,0,0,7,
		0,0,0,0,0,9,2,3,1,
		0,2,0,0,8,0,0,5,0,
		7,6,0,0,0,0,0,0,8,
		0,0,0,2,0,4,0,0,0,
		9,0,0,0,0,0,0,1,6,
		0,7,0,0,4,0,0,6,0,
		5,3,9,8,0,0,0,0,0,
		8,0,0,9,0,0,0,0,0
	};*/

/* 题目4 */
/*	int a[9][9] = {
		0,5,0,0,0,0,1,0,7,
		0,6,7,0,0,0,0,8,0,
		0,0,0,2,0,7,6,0,0,
		0,0,8,1,0,0,7,0,5,
		4,0,0,0,0,0,0,0,9,
		5,0,1,0,0,9,8,0,0,
		0,0,2,5,0,3,0,0,0,
		0,4,0,0,0,0,9,3,0,
		7,0,6,0,0,0,0,2,0
	};*/

/* 题目5 */
/*	int a[9][9] = {
		0,4,5,1,0,0,0,7,0,
		2,0,0,0,5,0,0,0,0,
		1,0,9,0,0,0,0,6,8,
		0,0,0,9,0,0,0,1,0,
		3,0,0,0,0,0,0,0,7,
		0,1,0,0,0,2,0,0,0,
		4,5,0,0,0,0,8,0,2,
		0,0,0,0,6,0,0,0,1,
		0,3,0,0,0,4,7,9,0
	};*/

	int b[9][9];

	/************************************************
	 * 将题目由a[][]复制到b[][]中
	 ************************************************/
	for ( int i = 0; i < 9; i ++ )
		for ( int j = 0; j < 9; j ++ )
			b[i][j] = a[i][j];

	/************************************************
	 * 调用solve函数求解数独并输出答案
	 * 红色表示答案
	 * 白色数字表示题目
	 ************************************************/
	solve( &a[0][0], &b[0][0], 0 );

	/************************************************
	 * 暂停,查看结果
	 ************************************************/
	system( "pause" );
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏日寒风Zoey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值