您的位置:首页 > 其它

Sudoku

2017-07-30 09:58 78 查看
Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.




Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107


Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127


这个题就是深搜啊,记录下空位的状态,然后深搜这些位置就好了。

主要是记录比较难弄,行列的话还是 row[行][某些值]=1,column[列][某些值]=1,某些值是1-9;最难记录的就是那九个小的方形,我们还是让emp_g[编号][某些值],主要就是这个编号的计算。

我们想赋值

0 1 2

3 4 5

6 7 8

我们想这样来编号,这样就可以确定方形位置,所以可以(i-1)/3*3+(j-1)/3,可以看到正好就是这样的赋值

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
/*
这个题一开始也是卡在怎么记录这个问题上,不知道怎样来解决这个问题
对于行和列,还比较好理解,就是row[i][num],column[j][num]
但是对于小正方形是不是满足条件,自己刚才还不是很理解这个问题
一共9个方格,我们对他们进行标号,这样就成了mark[标号][num],这样也就可以记录了,实在是妙啊
就是标号这个问题比较愁人。
*/

int mp[10][10];
int row[10][10],column[10][10],mark_square[10][10];//标记行,列,小正方形
int emp;
int flag;

typedef struct node
{
int x,y;
}Node;

Node emp_g[100];//记录这些空格子,我们的目的就是填满他们

int trans(int i,int j)
{
return ((i-1)/3)*3+(j-1)/3;//对每个小方格进行编号
}

void  dfs(int now)
{
if(now>emp)//填满了,我们就回去了
{
flag=1;
return ;
}
for(int i=1;i<=9;i++)//这个空格子我们可以选择的数
{
int row_now=emp_g[now].x,col_now=emp_g[now].y,id_now=trans(emp_g[now].x,emp_g[now].y);//先将这个空格所在的行 列 块标记出来

if(!row[row_now][i]&&!column[col_now][i]&&!mark_square[id_now][i])//如果i没有在空格的行 列 小方块中出现过
{
mp[emp_g[now].x][emp_g[now].y]=i; //填充值
row[row_now][i]=1,column[col_now][i]=1,mark_square[id_now][i]=1;//我们进行标记

dfs(now+1);//搜索下一个空格

if(flag)  break;//填完了,退出

mp[emp_g[now].x][emp_g[now].y]=0;     //没填完,将这个位置的信息还原
row[emp_g[now].x][i]=0,column[emp_g[now].y][i]=0,mark_square[trans(emp_g[now].x,emp_g[now].y)][i]=0;
}
}
}

int main()
{
int n;
scanf("%d",&n);
while(n--)
{
emp=0;flag=0;
memset(emp_g,0,sizeof(emp_g));
memset(mp,0,sizeof(mp));
memset(row,0,sizeof(row));
memset(column,0,sizeof(column));
memset(mark_square,0,sizeof(mark_square));//多组测试的把数据都清空

for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
scanf("%1d",&mp[i][j]);//这个%1d是什么鬼,中间没有空格符号,根本没有办法判断,他是不是一个数还是连续的几个数,所以我们规定输入的长度

int temp=mp[i][j];
if(temp!=0)
row[i][temp]=1,column[j][temp]=1,mark_square[trans(i,j)][temp]=1;
else
{
emp++;//数量信息,这样我们的记录就是从第一个开始的
emp_g[emp].x=i,emp_g[emp].y=j;//记录空格子的状态,信息
}
}
}

dfs(1);//现在进行第一个空格子的填数操作,也可以直接结构体,一会试一下

for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
printf("%d",mp[i][j]);
printf("\n");
}

}
return 0;
}


#include <iostream>
using namespace std;

int num,v[100][2],map[10][10];
//bool pd[10][10];  //判断输入的时候是否为零

bool judge(int x,int y,int k){
int i,j,it,jt;
for(i=0;i<9;i++){
if(map[i][y]==k) return false;
if(map[x][i]==k) return false;
}
it=(x/3)*3;
jt=(y/3)*3;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
if(map[i+it][j+jt]==k)
return false;
return true;
}

int dfs(int cap){
int i,x,y;
if(cap<0)
return 1;
for(i=1;i<=9;i++){
x=v[cap][0];
y=v[cap][1];
if(judge(x,y,i)){
map[x][y]=i;
if(dfs(cap-1))
return 1;
map[x][y]=0;
}
}
return 0;
}

int main(){
int t,i,j;
scanf("%d\n",&t);
while(t--){
num=0;
for(i=0;i<9;i++){
for(j=0;j<9;j++){
scanf("%1d",&map[i][j]);
if(map[i][j]==0){       //将为空的点的坐标全部记录下来,等下需要用暴力解决
v[num][0]=i;
v[num++][1]=j;
}
}
}
dfs(num-1);
for(i=0;i<9;i++){
for(j=0;j<9;j++)
printf("%d",map[i][j]);
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: