10117 : 数独游戏
问题描述
数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。
给你这样一个九宫格,你能求出这个数独的解么?保证数独有唯一解
输入格式
输入一个输入,每个数字表示对应位置的值,0表示该位置还为填数字。
输出格式
输入数独的解,格式如样例所示,行末无空格.
样例输入
000000000
002301000
000000076
900680000
000000400
001000200
000002104
000070000
600090000
样例输出
598746312
762351948
143829576
925684731
376215489
481937265
837562194
219478653
654193827
原题君~~~
#include <cstdio>
using namespace std;
struct NODE{
int x, y;
}b[85];
int a[10][10];//存储数独
int ling;//零的个数
int flag=0;//见dfs中作用
bool ma[10][10],mb[10][10],mc[10][10];//标记行列宫是否可填某数(空间换时间)
bool check (int x, int y, int s)
{
if (ma[x][s]==0&&mb[y][s]==0&&mc[(x-1)/3*3+(y+2)/3][s]==0)
return 1;//若横行数列宫格都满足填入的条件则填入
return 0;//否则不能填
}//判断坐标(x,y)是否可以填入s这个值
void dfs (int cnt)
{
if (cnt == ling+1)
{
flag=1;//由于输入保证有且只有一组解,所以找到后可直接返回。
return;//flag=1表示找到正解,以保证连续返回,不再浪费时间。
}//判断条件,若已经填入了所有需填的数,则说明找到了一组正解,返回
int x = b[cnt].x;
int y = b[cnt].y;//坐标的赋值
for (int i = 1; i <= 9; i++)//for循环尝试所有可能
if (check (x, y, i)==true)
{
a[x][y] = i;
ma[x][i]=1;
mb[y][i]=1;
mc[(x-1)/3*3+(y+2)/3][i]=1;//临时认为(x,y)填i
dfs (cnt+1);//向下一层搜
if(flag) return;//上述flag连续返回的执行
a[x][y] = 0;
ma[x][i]=0;
mb[y][i]=0;
mc[(x-1)/3*3+(y+2)/3][i]=0;//返回后发现(x,y)不能填i,取消之前的标记
}
}
int main()
{
for (int i = 1; i <= 9; i++)
for (int o = 1; o <= 9; o++)
{
scanf ("%1d", &a[i][o]);//这样可以做到一位一位读入
if (a[i][o]==0)//若这个位置为0
{
ling++;//ling统计需要填入数的格子的数目
b[ling].x=i;
b[ling].y=o;//b数组存储需要搜索的格子的坐标,所以用到了结构体
}
else//否则(即这个位置有确定的值)
{
ma[i][a[i][o]]=1;//标记横行不能填哪些数
mb[o][a[i][o]]=1;//标记纵列不能填哪些数
mc[(i-1)/3*3+(o+2)/3][a[i][o]]=1;//标记宫格不能填哪些数
}
}//输入
dfs (1);//开始搜索!
for (int i = 1; i <= 9; i++)
{
for (int o = 1; o <= 9; o++)
printf ("%d", a[i][o]);
printf ("\n");
}
return 0;
********~~~~~~********
}