<<The algorithm is beautiful>>——(7)——DFS Classic Question (2): Sudoku Game

content

Problem Description

problem analysis

 Code over:


Problem Description

As shown in [Figure 1.png], players need to deduce the numbers of all remaining spaces according to the known numbers on the 9×9 disk, and satisfy each

The numbers in each row, each column, and each of the nine palaces of the same color contain 1-9 without repetition.

 The answer to Sudoku is unique, so multiple solutions are also called no solutions.
The numbers in this picture are said to be difficult problems that Finnish mathematicians spent 3 months devising. But for you who can use computer programming, I am afraid it will be a piece of cake.
The requirement of this problem is to input the Sudoku problem, and the program outputs the unique solution of Sudoku. We guarantee that all known data formats are legal and that the problem has a unique solution.
Format requirements, input 9 lines, each line contains 9 numbers, 0 means unknown, other numbers are known.
Output 9 lines, each line of 9 numbers represents the solution of Sudoku.

For example:
input (that is, the title in the picture):

005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700


The program should output:

145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764


For another example, enter:

800000000
003600000
070090200
050007000
000045700
000100030
001000068
008500010
090000400


The program should output:

812753649
943682175
675491283
154237896
369845721
287169534
521974368
438526917
796318452


Resource convention:
Peak memory consumption < 256M
CPU consumption < 2000ms
Please output strictly according to the requirements, and do not superfluously print redundant content like: "Please enter...".
All code is placed in the same source file, after debugging, copy and submit the source code.
Note: The main function needs to return 0
Note: Only use the ANSI C/ANSI C++ standard, do not call special functions that depend on the compilation environment or operating system.
Note: All dependent functions must be explicitly #include <xxx> in the source file, and common header files cannot be omitted through project settings.
When submitting, take care to select the desired compiler type.

problem analysis

As for the requirements of Sudoku, everyone must be familiar with it. Every row, every column and every 3×3 small square cannot have the same number. So, now we can directly set the backtracking framework to solve.

The previous  backtracking algorithm is explained in detail , and the routine framework of the backtracking algorithm has been written. If you have not read that article, it is recommended to read it first .

Our idea of ​​solving Sudoku is very simple and crude, that is to exhaust all possible numbers in each grid. For each position, how exhaustive should be, and how many options are there?

It's very simple, from 1 to 9 is a choice, just try all of them once :

for (int k = 1; k < 10; k++)
		{
			if (check(ss, x, y, k))
			{
				ss[x][y] = (char)('0' + k);
				dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态
				//回溯在这里也可以
			}
		}
		ss[x][y] = '0';//回溯
	}

emmm, continue to refine, not all numbers from 1 to 9 can be obtained, don't some numbers not meet the legal conditions of Sudoku?

bool check(string* ss, int i, int j, int k)
{
	//检查同行和同列
	for (int l = 0; l < 9; l++)
	{
		if (ss[i][l] == (char)('0' + k))return false;
		if (ss[l][j] == (char)('0' + k))return false;
	}
	//处理小九宫格
	for (int l = (i / 3) * 3; l < (i / 3 + 1) * 3; l++)
	{
		for (int m = (j / 3) * 3; m < (j / 3 + 1) * 3; m++)
		{
			if (ss[l][m] == (char)('0' + k))return false;
		}
	}
	return true;
}

And now it's just  j adding one, what if it's  j added to the last column?

It's very simple, when it  j reaches the last index of each row, turn to increase  i and start to exhaust the next row, and add a judgment before exhaustion to skip the numbers that do not meet the conditions : (a little trick is used here)

	dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态

emmm, it's almost there now, there's one last problem left: this algorithm has no base case and will never stop recursing. This is easy to handle, when will the recursion end? Obviously, when it is equal to the last line, it means that the last line is exhausted, and all the exhaustion is completed, which is the base case .

if (x == 9)
	{
		print(ss);
		exit(0);
	}

Code over:

#include<iostream>
using namespace std;
void print(string* ss)
{
	for (int i = 0; i < 9; i++)
	{
		cout << ss[i] << endl;
	}
}
bool check(string* ss, int i, int j, int k)
{
	//检查同行和同列
	for (int l = 0; l < 9; l++)
	{
		if (ss[i][l] == (char)('0' + k))return false;
		if (ss[l][j] == (char)('0' + k))return false;
	}
	//处理小九宫格
	for (int l = (i / 3) * 3; l < (i / 3 + 1) * 3; l++)
	{
		for (int m = (j / 3) * 3; m < (j / 3 + 1) * 3; m++)
		{
			if (ss[l][m] == (char)('0' + k))return false;
		}
	}
	return true;
}
void dfs(string* ss, int x, int y)
{
	if (x == 9)
	{
		print(ss);
		exit(0);
	}
	if (ss[x][y] == '0')//虚以待位
	{
		for (int k = 1; k < 10; k++)
		{
			if (check(ss, x, y, k))
			{
				ss[x][y] = (char)('0' + k);
				dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态
				//回溯在这里也可以
			}
		}
		ss[x][y] = '0';//回溯
	}
	else {
		dfs(ss, x + (y + 1) / 9, (y + 1) % 9);//处理下一个状态
	}
}

int main()
{
	string* ss = new string[9];
	for (int i = 0; i < 9; i++)
	{
		cin >> ss[i];
	}
	dfs(ss, 0, 0);
	return 0;
}

 Okay, that's all for today, tired of studying xdm, the above picture relieves visual fatigue

Guess you like

Origin blog.csdn.net/m0_58367586/article/details/123946633