Luogu P1784 Sudoku problem solution (DFS solution)

This question obviously needs to use DFS (depth first search)

Note: There are other methods, but I use DFS here.

Title description

Sudoku is based on the known numbers on the 9×9 board, inferring all the numbers in the remaining spaces, and satisfying that the numbers in each row, column, and each bold line contain 1-9, and do not repeat. Every qualified Sudoku puzzle has and only has a unique answer. The reasoning method is also based on this. Any unsolved or multi-solved problem is unqualified.

A Finnish mathematician claimed to have designed the world's most difficult "Sudoku game" and published it in the newspaper for everyone to challenge.

The mathematician said that he believed that only the "smartest" people could solve the "Sudoku puzzle."

According to reports, the current difficulty level of Sudoku games is one to five, one is entry level, and five is more difficult. However, the mathematician said that the difficulty level of the Sudoku game he designed is eleven, which can be said to be the highest difficulty level in Sudoku games. He also said that he has not encountered a Sudoku game that he can't solve yet, so he believes that the "most challenging" Sudoku game has not appeared.

Input format

An unfilled Sudoku.

Output format

Completed Sudoku.

If you do not know the rules of Sudoku, please see the following passage know skip directly

Sudoku consists of 9×9 grids,

The rule is: each row, column, and palace must fill in numbers from 1-9, so that the numbers in each row, column, and palace are not repeated.

The palace is made up of 3×3 small grids

Insert picture description here

The time limit for this question is 1s, and the memory limit is 125M. DFS is not a big problem.

Code directly

#include<bits/stdc++.h>
using namespace std;
int a[15][15],b[15][15],c[15][15],g[15][15],flag=0;
/*开四个数组,a数组用来保存数独,b数组用来记录当前行是否出现过该数字,
c数组用来记录当前列是否出现过该数字,g数组用来记录当前宫格是否出现过该数字*/
void dfs(int x,int y)
{
    
    
	if(x>9)//当x大于9时说明矩阵已经被填满,已经找到数独的解,于是结束调用
	{
    
    
		flag=1;
		for(int i=1;i<=9;i++)
		{
    
    
			for(int j=1;j<=9;j++)
			cout<<a[i][j]<<' ';
			cout<<endl;
		}
		return;
	}
	if(a[x][y]==0)//如果当前位置未被占用,则进行填数,否则直接进入下一个位置
	for(int i=1;i<=9;i++)
	{
    
    
		if(flag)
		return;
		if(a[x][y]==0&&b[x][i]==0&&c[i][y]==0&&g[(x-1)/3*3+(y-1)/3+1][i]==0)
		a[x][y]=i,b[x][i]=1,c[i][y]=1,g[(x-1)/3*3+(y-1)/3+1][i]=1;//保存现场
		else continue;//(x-1)/3*3+(y-1)/3+1表示当前所在的宫格数,这里不做具体的数学证明
		if(y<9)
		dfs(x,y+1);
		else
		dfs(x+1,1);
		a[x][y]=0,b[x][i]=0,c[i][y]=0,g[(x-1)/3*3+(y-1)/3+1][i]=0;//恢复现场
	}
	else{
    
    
		if(y<9)
		dfs(x,y+1);
		else
		dfs(x+1,1);
	}
}
int main (void)
{
    
    
	for(int i=1;i<=9;i++)
	for(int j=1;j<=9;j++)
	{
    
    
		scanf("%d",&a[i][j]);
		if(a[i][j])
		b[i][a[i][j]]=1,c[a[i][j]][j]=1,g[(i-1)/3*3+(j-1)/3+1][a[i][j]]=1;
	}
	dfs(1,1);
}

The following is the test result

Insert picture description here

This is my evaluation record in Luoguzhong. The fastest DFS can run this question in 3ms, and the slowest is only 6ms.

Guess you like

Origin blog.csdn.net/qq_52758563/article/details/113188558