• 深度遍历破解数独游戏


    #include <iostream>
    #define N 9
    using namespace std;
    
    //判断该位置放置的数据是否符合规则
    bool panduan(int (*fang)[N],int row_now,int col_now,int count)
    {
    	//打印行列
    	//cout << row_now << "	" << col_now << endl;
    	//扫描本行是否有重复数据
    	int i,j;
    	for(i = 0;i < N;i++)
    	{
    		if( fang[row_now][i] == count && i != col_now)
    		{
    			return false;
    		}
    	}
    	//扫描本列是否有重复数据
    	for(i = 0;i < N;i++)
    	{
    		if( fang[i][col_now] == count && i != row_now)
    		{
    			return false;
    		}
    	}
    	//扫描本方块区域之内是否有重复数据
    	//扫描(0,0)区域
    	if(row_now < 3 && col_now < 3)
    	{
    		for(i = 0;i <= 2;i++)
    		{
    			for(int j = 0;j <= 2;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    	}
    	//扫描(0,1)区域
    	else if( row_now < 3 && col_now < 6 && col_now > 2)
    	{
    		
    		for(i = 0;i <= 2;i++)
    		{
    			for(j = 3;j <= 5;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    		
    	}
    	//扫描(0,2)区域
    	else if( row_now < 3 && col_now > 5)
    	{
    		for(i = 0;i <= 2;i++)
    		{
    			for(j = 6;j <= 8;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    	}
    	
    	
    	//扫描(1,0)区域
    	else if(row_now > 2 && row_now < 6 && col_now < 3)
    	{
    		
    		for(i = 3;i <= 5;i++)
    		{
    			for(j = 0;j <= 2;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    		
    	}
    	//扫描(1,1)区域
    	else if(row_now > 2 && row_now < 6 && col_now <6 && col_now > 2)
    	{
    		for(i = 3;i <= 5;i++)
    		{
    			for(j = 3;j <= 5;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    	}
    	//扫描(1,2)区域
    	else if(row_now > 2 && row_now < 6 && col_now > 5)
    	{
    		
    		for(i = 3;i <= 5;i++)
    		{
    			for(j = 6;j <= 8;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    		
    	}
    	
    	
    	//扫描(2,0)区域
    	else if(row_now > 5 && col_now < 3 )
    	{
    		
    		for(i = 6;i <= 8;i++)
    		{
    			for(j = 0;j <= 2;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    		
    	}
    	//扫描(2,1)区域
    	else if(row_now > 5 && col_now > 2 && col_now < 6)
    	{
    		
    		for(i = 6;i <= 8;i++)
    		{
    			for(j = 3;j <= 5;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    		
    	}
    	//扫描(2,2)区域
    	else if(row_now > 5 && col_now > 5)
    	{
    		for(i = 6;i <= 8;i++)
    		{
    			for(j = 6;j <= 8;j++)
    			{
    				//如果有重复数据 判断是不是自身
    				if( fang[i][j] == count )
    				{
    					//如果不是自身  就返回false
    					if( i != row_now && j != col_now)
    						return false;
    				}
    			}
    		}
    	}
    	
    	return true;
    }
    
    int count = 0;
    
    //计算程序
    void shudu(int (*fang)[N],int row_now,int col_now)
    {
    
    	//初始化数据副本
    	int fang2[N][N];
    	int i,j;
    	for(i = 0;i < N;i++)
    	{
    		for(j = 0;j < N;j++)
    		{
    			fang2[i][j] = fang[i][j];
    		}
    	}
    	//设计出口 如果当前行达到N 便说明递归完毕 可以输出
    	if(row_now == N )// && col_now == N - 1
    	{
    		cout << "方案" << ++count << ":" << endl;
    		//输出
    		for(i = 0;i < N;i++)
    		{
    			for(j = 0;j < N;j++)
    			{
    				cout << fang2[i][j];
    			}
    			cout << endl;
    		}
    		cout << endl << endl;
    	}
    	else
    	{
    		//如果本位置不为0 说明本位置不需要放置数据 则进行下一列的判断
    		if(fang2[row_now][col_now] != 0)
    		{
    			//如果尚未到达行尾 便进行下一列
    			if(col_now < N - 1)
    			{
    				shudu(fang2,row_now,col_now+1);
    			}
    				
    			//如果已经到达了行尾 便进行换行
    			else
    			{
    				shudu(fang2,row_now+1,0);
    			}
    		}
    		
    		//如果本位置为0 说明该位置需要放置数据
    		else
    		{
    			//放置的数据为1~9	进列逐一判断填放
    			for(int count = 1;count <= 9;count++)
    			{
    				//清空本位置数据 即回复为0	以便下一次放置数据
    				fang2[row_now][col_now] = 0;
    
    				//该位置放置该数据如果符合规则
    				if ( panduan(fang2,row_now,col_now,count) )
    				{
    					//放置该数据在本位置
    					fang2[row_now][col_now] = count;
    					
    					//该位置放置合法数据之后 进行下一个位置的递归判断
    					
    					//如果尚未到达行尾 便进行下一列
    					if(col_now < N - 1)
    					{
    						shudu(fang2,row_now,col_now+1);
    					}
    					//如果已经到达了行尾 便进行换行
    					else
    					{
    						shudu(fang2,row_now+1,0);
    					}
    				}
    			}	
    		}
    	}
    }
    
    
    int main()
    {
    	//打印游戏规则
    	cout << "游戏规则:需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复" << endl;
    	cout << "每行输入9个数字 共输入9行 需要空出的方格位置用0表示" << endl;
    	int fang[N][N];
    
    	char fang_char[N][N];
    	int i,j;
    	//初始化数独
    	for(i = 0;i < N;i++)
    	{
    		for(j = 0;j < N;j++)
    		{
    			cin >> fang_char[i][j];
    			fang[i][j] = ((int)fang_char[i][j])-48;
    		}
    	}
    	
    	cout << endl << endl;
    
    	//进入计算程序
    	int row_now = 0,col_now = 0;
    	count = 0;
    	shudu(fang,row_now,col_now);
    	cout << "以上为可行解!" << endl;
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    ReenTrantLock可重入锁(和synchronized的区别)总结
    什么是死锁?如何解决死锁?【转载】
    android studio 完整安装教程,已完全实践过
    foxmail创建163公司企业邮箱的时候会出现ERR Unable to log on
    Android 开发 res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)
    android studio 突然出现Gradle project sync failed 错误
    android 开发edittext获取焦点时hint消失
    Z480联想笔记本突然没有了声音
    android聊天,存储聊天记录sqlite
    adb shell出现error错误
  • 原文地址:https://www.cnblogs.com/maskerk/p/7348918.html
Copyright © 2020-2023  润新知