WOJ1478 Sudo..ku

Time Limit: 1 second

Memory Limit: 512 mebibytes

One day, somebody talk to Mr.G : Do you know JCVB have been the champion of the world Sudoku championships. He can solve a Sudoku Crosswords in a minute. Mr.G said: Just so so.If give me a computer I can solve the problem in a second. But later he found his program couldn’t solve the problem only use 1 second. So, he gave the problem to you. Can you help him to solve the crossword?

Iuput

The input contains 9 lines, and each line contains 9 integers S i , 1 , S i , 2 , … S i , 9 S_{i,1}, S_{i,2}, \ldots S_{i,9} Si,1,Si,2,Si,9, describes the sudoku.
0 ≤ S i , j S_{i,j} Si,j≤9, S i , j S_{i,j} Si,j=0 means the box(i,j) is empty.

Output

Print the whole crossword in the same format as input.

If there are multiple answers, output anyone of them. The answer exists.

Examples

Sample Input

2 0 0 0 1 0 8 9 0
0 0 7 0 0 0 0 0 0
0 0 0 9 0 0 0 0 7
0 6 0 0 0 1 3 0 0
0 9 0 7 3 4 0 8 0
0 0 3 6 0 0 0 5 0
6 0 0 0 0 2 0 0 0
0 0 0 0 0 0 1 0 0
0 5 9 0 8 0 0 0 3

Sample Output

2 4 5 3 1 7 8 9 6
9 1 7 2 6 8 5 3 4
3 8 6 9 4 5 2 1 7
4 6 2 8 5 1 3 7 9
5 9 1 7 3 4 6 8 2
8 7 3 6 2 9 4 5 1
6 3 8 1 7 2 9 4 5
7 2 4 5 9 3 1 6 8
1 5 9 4 8 6 7 2 3.

Note

Don’t think too much, just use … brute force?

#include <stdio.h>
#include <stdlib.h>

/* 子函数流程:
 * 1 dfs搜索结束的条件
 * 2 开始回溯的条件
 * 3 正常情况下填入数字的流程
 */
void dfs(int Sudoku[9][9], int row, int col)
{
    int count = 0, d[9] = {0}; //d是用来记录每一个可填入数的一维数组
    int i, j;
    //搜索结束,行列都累加到9
    if(row==9 && col==9)
    {
        for(i=0; i<9; i++)
        {
            for(j=0; j<9; j++)
                printf("%d ", Sudoku[i][j]);
            printf("\n");
                
        }
        return ;
    }
   //开始回溯,即此格为0,需要填入数字
    if(Sudoku[row][col] == 0)
    {
        for(int k=0; k<9; k++)
        {
            //行检验
            if(Sudoku[row][k] != 0)
            {
                d[Sudoku[row][k]-1] = 1;  //记录这个数字表示已有
            }
            //列检验
            if(Sudoku[k][col] != 0)
            {
                d[Sudoku[k][col]-1] = 1;
            }
        }
        //块检验
        for(int m=(int)(row/3)*3; m<(int)(row/3)*3+3; m++)
        {
            for(int n=(int)(col/3)*3; n<(int)(col/3)*3+3; n++)
            {
                if(Sudoku[m][n] != 0)
                    d[Sudoku[m][n]-1] = 1;
            }
        }
        for(int k=0; k<9; k++)
            if(d[k] == 0)
                count++;
        if(count == 0) //解不对
            return;
        //有解时,填入d中记录可填入的数,再进行对行列数进入到下一个的操作,如
        //若下一个满足回溯条件跳回原来的,则之前改变的还原
        else
        {
            for(int k=0; k<9; k++)
            {
                if(d[k] == 0)
                {
                    //填入d中记录的可填入数
                    Sudoku[row][col] = k+1;
                    d[k] = 1;
                    //再进行对行列数进入下一个的操作 
                    //依次从左到右,从上到下
                    if(col == 8 && row == 8)
                    {
                        col++;
                        row++;
                    }
                    else if(col == 8 && row < 8)
                    {
                        col = 0;
                        row++;
                    }
                    else if(col<8 && row <= 8)
                    {
                        col++;
                    }
                    dfs(Sudoku, row, col); //进入下一格
                    //如果下一个满足回溯条件跳回原来的,则之前的改变还原
                    if(col == 0)
                    {
                        col = 8;
                        row--;
                    }
                    else
                    {
                        col--;
                    }
                    Sudoku[row][col] = 0;
                    d[k] = 0;
                }
            }
        }
    }
    else //这一格中已经提供了数,则进行行列数的操作后,直接进入下一格
    {
        if(col == 8 && row == 8)
        {
            col++;
            row++;
        }
        else if(col == 8 && row < 8)
        {
            col = 0;
            row++;
        }
        else if(col <8 && row <=8)
        {
            col++;
        }
        dfs(Sudoku, row, col); //进入下一格
    }
}


int main()
{
    int Sudoku[9][9];
    int i, j;
    int row = 0, col=0; 
    for(i=0; i<9; i++)
        for(j=0; j<9; j++)
            scanf("%d", &Sudoku[i][j]);
    dfs(Sudoku, row, col);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值