回溯算法求解数独问题(C++ 递归/非递归)

数独求解
如何使用求解上述数独?

递归实现

#include<bits/stdc++.h>

using namespace std;

int sudoku[9][9];
int dx[9]= {-1,-1,-1,0,0,0,1,1,1},dy[9]={-1,0,1,-1,0,1,-1,0,1};
 
void print(){
	for(int i=0;i<9;i++){
		for(int j=0;j<9;j++)
			cout << sudoku[i][j] << " ";
		cout << endl;
	}
}
bool check(int i,int j, int num){ // (i,j)位置填入num判断是否合适 
	for(int k=0;k<9;k++){   // 所在行和列判断 
		if(sudoku[i][k]==num||sudoku[k][j]==num){
			return false;
		}
	}
	int cx = i/3*3+1, cy = j/3*3+1;
	for(int k=0;k<9;k++){                   // 九宫格 
		int cur_x = cx+dx[k],cur_y = cy+dy[k];
		if(sudoku[cur_x][cur_y]==num)
			return false;
	}
	return true;
}
void  search(int i,int j){
	if(i==8&&j==9) {
		print();
		return ;
	}
	if(j==9){
		i++;
		j=0;
	}
	if(sudoku[i][j]==0){
		for(int num=1;num<=9;num++){
			if(check(i,j,num)){
				sudoku[i][j] = num;
				search(i,j+1);
				sudoku[i][j] = 0;
			}
		}
	}
	else 
		search(i,j+1);
}
int main(){
	for(int i=0;i<9;i++)
		for(int j=0;j<9;j++)
			cin >> sudoku[i][j];	
	search(0,0);	
	return 0;
}

 

非递归实现

非递归回溯求解数独问题,每次在9*9的矩阵中按行优先寻找第一个不为0的位置
并将该位置进栈,然后对该位置进行从num=1到9试填,并check该位置放num是否合适,
如果不合适就将该点出栈,同时将值置为0,否则就放入num,然后将下一个0位置进栈…

#include<bits/stdc++.h> 
using namespace std;



int sudoku[9][9];
int dx[9]= {-1,-1,-1,0,0,0,1,1,1},dy[9]={-1,0,1,-1,0,1,-1,0,1};
void print(){
	for(int i=0;i<9;i++){
		for(int j=0;j<9;j++)
			cout << sudoku[i][j] << " ";
		cout << endl;
	}
}
bool check(int i,int j, int num){ // (i,j)位置填入num判断是否合适 
	for(int k=0;k<9;k++){   // 所在行和列判断 
		if(sudoku[i][k]==num||sudoku[k][j]==num){
			return false;
		}
	}
	int cx = i/3*3+1, cy = j/3*3+1;
	for(int k=0;k<9;k++){                   // 九宫格 
		int cur_x = cx+dx[k],cur_y = cy+dy[k];
		if(sudoku[cur_x][cur_y]==num)
			return false;
	}
	return true;
}
int find(){
	for (int i = 0;i<81;i++)
		if (!sudoku[i/9][i%9])
			return i;
	return -1;
}
bool solve(){   // 非递归回溯 
	stack<int> st;
	st.push(find());
	int num;
	while(!st.empty()&&(st.top()>=0)){
		int x = st.top()/9, y = st.top()%9;
		for(num = sudoku[x][y]+1;num<=9&&(!check(x,y,num));num++);
		if(num>9){
			sudoku[x][y] = 0;
			st.pop();	
		}
		else {
			sudoku[x][y] = num;
			st.push(find());
		}	
	} 
	return (!st.empty());
}


int main()
{
	for(int i=0;i<9;i++)
		for(int j=0;j<9;j++)
			cin >> sudoku[i][j];
	if(solve()){
		print();	
	}
	else cout << "无解" << endl; 
	return 0;
}
发布了63 篇原创文章 · 获赞 34 · 访问量 6562

猜你喜欢

转载自blog.csdn.net/SinclairWang/article/details/103317547