数独(dfs解)

蒜头君今天突然开始还念童年了,想回忆回忆童年。他记得自己小时候,有一个很火的游戏叫做数独。便开始来了一局紧张而又刺激的高阶数独。蒜头君做完发现没有正解,不知道对不对? 不知道聪明的你能否给出一个标准答案?

标准数独是由一个给与了提示数字的 9×9 网格组成,我们只需将其空格填上数字,使得每一行,每一列以及每一个 3×3 宫都没有重复的数字出现。

输入:

* 2 6 * * * * * *
* * * 5 * 2 * * 4
* * * 1 * * * * 7
* 3 * * 2 * 1 8 *
* * * 3 * 9 * * *
* 5 4 * 1 * * 7 *
5 * * * * 1 * * *
6 * * 9 * 7 * * *
* * * * * * 7 5 *

输出:

1 2 6 7 3 4 5 9 8
3 7 8 5 9 2 6 1 4
4 9 5 1 6 8 2 3 7
7 3 9 4 2 5 1 8 6
8 6 1 3 7 9 4 2 5
2 5 4 8 1 6 3 7 9
5 4 7 2 8 1 9 6 3
6 1 3 9 5 7 8 4 2
9 8 2 6 4 3 7 5 1

提醒:两个数字之间要有一个空格,其他地方不要输出多余的符号

示例代码:

/**
	关于数组xv,yv,vv起的标记作用
	其思想其实也很简单,就是做到数独上面的格子能够和xv,yv,vv上的格子有个对应关系 
	感觉深搜基本上都会用到数组标记的技巧(用来回溯) 
*/ 
#include<cstdio>
char s[10][10];	//存储"棋盘"上的数据 
bool xv[10][10], yv[10][10], vv[10][10];	//用来标记行、列、3x3格子填过数的位置
bool f;	
void dfs(int x, int y) {
	
	if(f) {
		return;
	}
	
	if( x == 9 ) {	    //x为9 说明所有的行都填数完毕 
		f = true;
		//所有数字都已经填完,输出填完之后的数独"棋盘" 
		for (int i = 0; i < 9; i ++) {
			for (int j = 0; j < 9; j ++) {
				
				if(j == 8) {
					printf("%c\n",s[i][j]);
				} else {
					printf("%c ",s[i][j]);
				}
					
			}
		}
		return;
	}
	
	if( y == 9 ) {	    //y为9说明填好一行 
		dfs(x + 1, 0);  //换一行继续填 
		return;
	}
	
	if(s[x][y] != '*') {
		dfs(x, y + 1);
		return;
	}
	
	for(int i = 1; i <= 9; i ++) {
	//printf("%d %d %d\n",x, y, i);
		//在符合条件的位置上填数
		if(!xv[x][i] && !yv[y][i] && !vv[x / 3 * 3 + y / 3][i]) {
			xv[x][i] = yv[y][i] = vv[x / 3 * 3 + y / 3][i] = true;    //已经填过的数在对应、列、3x3方格上做好标记
			s[x][y] = i + '0';    //填入数字
			dfs(x, y + 1);
			xv[x][i] = yv[y][i] = vv[x / 3 * 3 + y / 3][i] = false;    //取消填过的数(深搜到某一步发现当前解不符合条件时需要回溯上一个dfs(int x,int y),此时需要取消历史填数以便进行其他试探)
			s[x][y] = '*';
		}
	}
	
}
int main() {
	//输入一个原始的数独数据 
	for(int i = 0; i < 9; i ++ ) {
		for (int j = 0; j < 9; j ++) {
			
			scanf(" %c",&s[i][j]);	//" %c"留了一个空格是为了吃掉输入中的空格
			 
			//将已经填好数字的位置 通过 xv yv vv数组做个标记 
			if(s[i][j] != '*') {	
				xv[i][s[i][j] - '0'] = true;
				yv[j][s[i][j] - '0'] = true;
				vv[i / 3 * 3 + j / 3][s[i][j] - '0'] = true;
			}
		}
	}
	dfs(0, 0);
	return 0;
}
posted @ 2020-02-13 23:50  橡北  阅读(863)  评论(0)    收藏  举报