#include <iostream>
#define N 9
using namespace std;
//判断该位置放置的数据是否符合规则
bool panduan(int (*fang)[N],int row_now,int col_now,int count)
{
//打印行列
//cout << row_now << "\t" << 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;
}