1. 程式人生 > >dfs(0634-數獨)

dfs(0634-數獨)

urn 是把 image main dfs搜索 true 流行 搜索 etc

問題描述

數獨是非常流行的益智遊戲,把一個9x9的九宮格分成9個小的3x3的小九宮,如下圖所示。在這個九宮格上,每個小格子可以填的數字為1,2,3,...,9。初始時,某些格子已經填好數字,剩余的一些則為空白,你的任務是把空白的數字都填上1,2,3,...,9數字的一個,使得表格上每一行、每一列、以及每一個小九宮均含有有1,2,3,...,9(顯然每個數字在每行、每列和每個小九宮中都出現並且只能出現一次)。請你寫一個程序解決數獨問題。
技術分享

輸入

輸入為9行,每行9個數字,其中0代表對應的小格子為空白的格子。

輸出

輸出為9行,每行9個有1,2,3,...,9構成的數字。即數獨問題的解。

輸入樣列
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107
輸出樣例
143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127
說一下思路吧,我是參考黃學長的~就是將每一行每一列每一個九宮格標記一下,然後dfs搜索,註意邊界和搜索完要保持原先的狀態即可~
#include<bits/stdc++.h>
#define Next(x,y) y==9 ? dfs(x+1,1) : dfs(x,y+1)
using namespace std;

int a[10][10],b[10][10];
bool l[10][10],r[10][10],s[10][10];
int Map[10][10];

int fill(int x,int y,int k)
{
	if(l[x][k]||r[y][k]||s[Map[x][y]][k]) return 0;
	b[x][y]=k;
	l[x][k]=r[y][k]=s[Map[x][y]][k]=1;
	return 1;
}

void del(int x,int y,int k)
{
	b[x][y]=0;
	l[x][k]=r[y][k]=s[Map[x][y]][k]=0;
}

void print()
{
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++)
			cout<<b[i][j]<<"";
			cout<<"\n";}
}

void dfs(int x,int y)
{
	if(x==10&&y==1)
	{
		print();exit(0);
	}
	if(b[x][y]) Next(x,y);
	else
	{
		for(int i=1;i<=9;i++)
		{
			if(fill(x,y,i))
			{
				Next(x,y);
				del(x,y,i);//搜過之後要刪除 
			}
		}
	}
}

void init()
{
	for(int i=1;i<=9;i++)
		for(int j=1;j<=9;j++)
			Map[i][j]=(i-1)/3*3+(j-1)/3+1;
}

int main()
{
	char str;
	init();
	/*for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++)
			cout<<Map[i][j]<<" ";
			cout<<"\n";}*/
	for(int i=1;i<=9;i++)
	{
		for(int j=1;j<=9;j++)
		{
			str=getchar();
			a[i][j]=str-‘0‘;
			if(a[i][j])
				fill(i,j,a[i][j]);
		}
		getchar();
	}
	dfs(1,1);
	/*for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++)
			cout<<s[i][j]<<" ";
			cout<<"\n";}*/
}

dfs(0634-數獨)