NYOJ 722 数独

来源:互联网 发布:mac os 最新版本 .cdr 编辑:程序博客网 时间:2024/05/17 22:52

数独

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

         数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个3*3宫内的数字均含1-9,不重复。 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

       有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它。。


输入
第一行有一个数n(0< n <100),表示有n组测试数据,每组测试数据是由一个9*9的九宫格构成,0表示对应的格子为空
输出
输出一个9*9的九宫格,为这个数独的答案
样例输入
10 0 5 3 0 0 0 0 08 0 0 0 0 0 0 2 00 7 0 0 1 0 5 0 04 0 0 0 0 5 3 0 00 1 0 0 7 0 0 0 60 0 3 2 0 0 0 8 00 6 0 5 0 0 0 0 90 0 4 0 0 0 0 3 00 0 0 0 0 9 7 0 0
样例输出
1 4 5 3 2 7 6 9 8 8 3 9 6 5 4 1 2 7 6 7 2 9 1 8 5 4 3 4 9 6 1 8 5 3 7 2 2 1 8 4 7 3 9 5 6 7 5 3 2 9 6 4 8 1 3 6 7 5 4 2 8 1 9 9 8 4 7 6 1 2 3 5 

5 2 1 8 3 9 7 6 4

 


核心:就是从一条路走到黑,如果可以就继续,不可以的话就一步一步的往后退

#include<stdio.h>
#include<string.h>
bool col[9][10];  //构造一个9*10的数组,例如:第一行第五个数字代表数字5,如果这个数字可以填进去的话,就标记为1: 
bool row[9][10];  //同上 
bool black[3][3][10];//将一个大的81宫格,平分成9个9宫格,例如:如果第一行第一列的九宫格中的第六位数字代表6,如果可以填进去就标记成1; 
int map[9][9];     //读进去的题中的数字 
int flag;
void dfs(int k)
{
if(flag)      //剪枝 
return ;
int i,j;
int r=k/9,c=k%9;     //求出几行几列 

if(k==81)         //因为从0开始,第80个数就表示第81个数 
{
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
printf("%d ",map[i][j]);
printf("\n");
}
flag=1;
return ;
}
if(map[r][c]==0)          //如果是0,就开始搜 
{
for(i=1;i<=9;i++)
{
if(!(row[r][i] || col[c][i] || black[r/3][c/3][i]))  //如果这个数字还没有被用过 ,即行中列中以及小九宫格中都没有出项过 
{
map[r][c]=i;        //没有出现过i,所以赋值 
row[r][i]=1;          //标记成已出项过 
col[c][i]=1;
black[r/3][c/3][i]=1;
dfs(k+1);       //向下走的入口,(不满足时向上走的出口) 
map[r][c]=0;       //@@@@这个是dfs走到头之后,发现没法走下去的时候,返回来,一次退一步 
row[r][i]=col[c][i]=0;///消去标记 
black[r/3][c/3][i]=0;
}

}
else 
dfs(k+1);   //如果这个数字是题中给的 ,则进行下一个搜索 

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(col,0,sizeof(col));
memset(row,0,sizeof(row));
memset(black,0,sizeof(black));
int i,j;
flag=0;
for(i = 0; i < 9; i++)
{
for(j = 0; j < 9; j++)
{
scanf("%d", &map[i][j]);
if(map[i][j])         //如果题中的这个位置的数字不是0,说明不用判断这个数字,那么就做以下标记 
{
row[i][map[i][j]] = 1;
col[j][map[i][j]] = 1;
black[i/3][j/3][map[i][j]] = 1;
}
}
}
dfs(0);              //开始深搜 

return 0;
}

1 0
原创粉丝点击