巧用dfs解数独问题——算法笔记

巧妙的用 n 表示 第n/9行第n%9列 (0是第一个数)。
巧妙的用 row = (n/9)/33; col = n%9/33; 表示数独里面的小正方形(行、列)。那么遍历数独就至于要一个 n即可。 (0<=n < 81)
因为数独答案唯一,所以只要找到一个正确的,就可以 exit(0); 了。

#include 
#include 		//exit(0)	强制退出。(数独只有唯一解) 

using namespace std;

int a[9][9];

//n为第n/9行第n%9列		//巧妙的用 n 表示了 行&列中所有位置 
bool judge(int n,int i)		//判断  第n/9行第n%9列  数字 i 是否合法 
{
     
	for(int j=0;j<9;j++)
	{
     
		if(a[n/9][j] == i)		//检查行是否合法 
			return false;
		if(a[j][n%9] == i)		//检查列是否合法
			return false;
	}
	
	int row = (n/9)/3*3;	//检查小正方形 	(这个方法好巧妙!利用n控制了小正方形)  40  4行4列  (3,3)--(5,5) 
	int col = n%9/3*3;
	for(int b=row;b<=row+2;b++)	
	{
     
		for(int c=col;c<=col+2;c++)
		{
     
			if (a[b][c]==i)
			{
     
				return false;
			}
				
		}
	}
		
	return true;
} 

void dfs(int n)
{
     
	if(n==81)		//出口 
	{
     
		cout << "\n\n答案是:\n" << endl;
		for(int i=0;i<9;i++)
		{
     
			for(int j=0;j<9;j++)
			{
     
				cout<<a[i][j];
			}	
			cout<<endl; 
		}
		exit(0);		//因为答案唯一,所以可以直接退出 
	}
	
	if(a[n/9][n%9])		//该点被填了,就填下一个点
	{
     
		dfs(n+1);
	} 
	else
	{
     
		for(int i=1;i<=9;i++)	//1~9开始填数字 
		{
     
			if(judge(n,i))
			{
     
				a[n/9][n%9] = i;
				dfs(n+1);
				a[n/9][n%9] = 0;	//回溯 
			}			
		}	
	}
} 

int main()
{
     
	char temp;
	
	for(int i=0;i<9;i++)	//input
	{
     
		for(int j=0;j<9;j++)
		{
     
			cin>>temp;
			a[i][j] = temp-'0';
		}
	}
		
	dfs(0);
	
	return 0;
} 

你可能感兴趣的:(C++算法笔记)