UVa 989 - Su Doku

题目:数独。填充大小为1x1,4x4,9x9数独。

分析:搜索。直接利用dfs回溯求解。存储每行,每列,每个子块的数字使用情况,优化搜索。

说明:对于解有顺序要求,DL超时了 - -。

#include <cstring>
#include <cstdio>

int data[9][9];
int b_id[9][9];
int visit_r[10][10];
int visit_c[10][10];
int visit_b[10][10];

int position[81];
int dfs(int k, int size, int n)
{
	if (k == size) {
		return 1;
	}
	int p = position[k];
	int r = p/(n*n), c = p%(n*n), b = r/n*n + c/n;
	for (int v = 1; v <= n*n; ++ v) {
		if (!visit_r[r][v] && !visit_c[c][v] && !visit_b[b][v]) {
			visit_r[r][v] = 1;
			visit_c[c][v] = 1;
			visit_b[b][v] = 1;
			data[r][c] = v;
			if (dfs(k+1, size, n)) {
				return 1;
			}
			visit_r[r][v] = 0;
			visit_c[c][v] = 0;
			visit_b[b][v] = 0;
		}
	}
	return 0;
} 

int main()
{
	int n, t = 0;
	while (~scanf("%d",&n)) {
		if (t ++) {
			printf("\n");
		}
		for (int i = 0; i < n*n; ++ i) {
			for (int v = 1; v <= n*n; ++ v) {
				visit_r[i][v] = 0;
				visit_c[i][v] = 0;
				visit_b[i][v] = 0;
			}
		}
		int size = 0;
		for (int i = 0; i < n*n; ++ i) {
			for (int j = 0; j < n*n; ++ j) {
				scanf("%d",&data[i][j]);
				b_id[i][j] = i/n*n + j/n;
				if (data[i][j] == 0) {
					position[size ++] = i*n*n + j;
				}else {
					visit_r[i][data[i][j]] = 1;
					visit_c[j][data[i][j]] = 1;
					visit_b[b_id[i][j]][data[i][j]] = 1;
				}
			}
		}
		
		if (dfs(0, size, n)) {
			for (int i = 0; i < n*n; ++ i) {
				for (int j = 0; j < n*n; ++ j) {
					if (j) {
						printf(" ");
					}
					printf("%d",data[i][j]);
				}
				printf("\n");
			}
		}else {
			printf("NO SOLUTION\n");
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值