数独游戏【DFS】

>Link

ybtoj数独游戏


>解题思路

这一道题据zzl大佬所说跟八皇后问题很像(找了一下发现我当时没有写八皇后的博客
为了使每一行每一列每一宫每一个数字只存在一个,可以建一个变量 h i , j h_{i,j} hi,j表示第 i i i行是否存在数字 j j j,列和宫类似
然后通过所在区域是否存在当前数字进行剪枝

宫可以暴力进行判断✔


>代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int a[100];
string s;
bool ans, h[20][20], l[20][20], g[20][20];

int getG (int x)
{
    
    
	int H = x / 9 + 1;
	int L = x % 9;
	if (x % 9 == 0) H--, L = 9;
	if (H <= 3)
	{
    
    
		if (L <= 3) return 1;
		if (L <= 6) return 2;
		if (L <= 9) return 3;
	}
	if (H <= 6)
	{
    
    
		if (L <= 3) return 4;
		if (L <= 6) return 5;
		if (L <= 9) return 6;
	}
	if (L <= 3) return 7;
	if (L <= 6) return 8;
	return 9;
}
void dfs (int now)
{
    
    
	if (ans) return;
	if (now == 81 + 1)
	{
    
    
		ans = 1;
		for (int i = 1; i <= 81; i++) printf ("%d", a[i]);
		printf ("\n");
		return;
	}
	if (a[now] != 0) {
    
    dfs (now + 1); return;} 
	int H = now / 9 + 1;
	int L = now % 9;
	if (now % 9 == 0) H--, L = 9;
	int G = getG (now);
	for (int i = 1; i <= 9; i++)
	  if (!h[H][i] && !l[L][i] && !g[G][i])
	  {
    
    
	  	a[now] = i;
		h[H][i] = l[L][i] = g[G][i] = 1;
		dfs (now + 1);
		a[now] = 0;
		h[H][i] = l[L][i] = g[G][i] = 0;
	  }
}

int main()
{
    
    
	cin >> s;
	while (s != "end")
	{
    
    
		ans = 0;
		memset (a, 0, sizeof (a));
		memset (h, 0, sizeof (h));
		memset (l, 0, sizeof (l));
		memset (g, 0, sizeof (g));
		for (int i = 1; i <= 81; i++)
		  if (s[i - 1] != '.')
		  {
    
    
		  	a[i] = s[i - 1] - '0';
			int H = i / 9 + 1;
			int L = i % 9;
			if (i % 9 == 0) H--, L = 9;
		  	h[H][a[i]] = l[L][a[i]] = g[getG (i)][a[i]] = 1;
		  }
		dfs (1);
		cin >> s;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/112966185