【蓝桥杯试题】盾神与困难数独

问题描述

有一天,盾神接触到了风靡世界的小游戏——数独!!!盾神非常感兴趣,不惜翘课用了一天的时间把数独玩得出神入化!!!于是他要过来考考你。经过“盾神与简单数独”的磨练后,你会做9*9的了。

输入格式

输入为9*9的矩阵,如果第i行第j列为0,则该格子未填数;否则该格子已经有数。

输出格式

输出为1个9*9的矩阵,表示字典序最小的方案。如无解则输出NO。
  矩阵大小关系的定义:第一关键字为a[1][1],第二关键字为a[1][2],……第四关键字为a[1][4],第五关键字为a[2][1],以此类推。矩阵A小于矩阵B,当且仅当存在k,A和B的前k-1个关键字的值都相等,而A的第k个关键字的值小于B的第k个关键字的值。矩阵A等于矩阵B,当且仅当A小于B和B小于A都不成立。
  字典序升序的定义:在矩阵序列a中,对于任意的i<=j,有a[i]<=a[j]。

样例输入

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

样例输出

NO

样例输入

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

样例输出

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 2 9 7 8
6 4 2 9 7 8 5 3 1
9 7 8 5 3 1 6 4 2
数据规模和约定
矩阵中所有数的值为0到9。

题解

数独定义:
在这里插入图片描述
dfs+回溯,和方块填数非常像,但是我漏了一个数独非常重要的条件,也就是每一个粗线宫(3*3)内的数字也是只含1-9不能重复(连数独都忘了怎么玩了)。
【蓝桥杯试题】盾神与困难数独_第1张图片

代码

#include
#include
using namespace std;
vector<vector<int> > matrix(9, vector<int>(9));//数独矩阵
vector<vector<bool> > rowFlag(9, vector<bool>(10, 0));//行标记
vector<vector<bool> > colFlag(9, vector<bool>(10, 0));//列标记
vector<vector<bool> > groupFlag(9, vector<bool>(10, 0));//小组标记

int dfs(int num) {
	if (num == 81) {//递归边界
		for (int i = 0; i < 9; ++i) {
			for (int j = 0; j < 9; ++j) {
				cout << matrix[i][j] << " ";
			}
			cout << endl;
		}
		return 1;
	}
	//计算row,col
	int x = num / 9, y = num % 9,groupIndex;
	//将坐标转换成对应的小组序号
	groupIndex = (x / 3) * 3 + (y / 3);
	//dfs+回溯
	if (matrix[x][y] == 0) {
		for (int i = 1; i <= 9; ++i) {
			if (rowFlag[x][i] == 0 && colFlag[y][i] == 0 && groupFlag[groupIndex][i] == 0) {
				matrix[x][y] = i;
				rowFlag[x][i] = 1;
				colFlag[y][i] = 1;
				groupFlag[groupIndex][i] = 1;
				if (dfs(num + 1))
					return 1;
				groupFlag[groupIndex][i] = 0;
				matrix[x][y] = 0;
				rowFlag[x][i] = 0;
				colFlag[y][i] = 0;
			}
		}
	}
	else {
		if (dfs(num + 1))
			return 1;
	}
	return 0;
}

int main() {
	for (int i = 0; i < 9; ++i) {
		for (int j = 0; j < 9; ++j) {
			cin >> matrix[i][j];
			if (matrix[i][j] != 0) {
				int groupIndex = (i / 3) * 3 + (j / 3);
				//如果在输入的时候发现已经不满足条件,直接输出NO并结束
				if (rowFlag[i][matrix[i][j]] || colFlag[j][matrix[i][j]] || groupFlag[groupIndex][matrix[i][j]] ) {
					cout << "NO";
					return 0;
				}
				rowFlag[i][matrix[i][j]] = 1;
				colFlag[j][matrix[i][j]] = 1;
				groupFlag[groupIndex][matrix[i][j]] = 1;
			}
		}
	}
	if (dfs(0) == 0)cout << "NO";
	//system("pause");
	return 0;
}

评测结果:
请添加图片描述

你可能感兴趣的:(蓝桥杯备战,算法,蓝桥杯)