Sudoku (dfs solution)

Garlic also read monarch Today, suddenly began to childhood, and want to recall memories of childhood. He remembered his childhood, there is a very fire of the game is called Sudoku. A bureau began to tense and exciting high-order only. Jun garlic finish found no positive solution, do not you think? I do not know the answers you can give a standard answer?

By a number of standard only give a 9 × 9 grid numbers prompted composition, we just need to fill a space numbers, so that each row, column, and a 3 × 3 every house no duplicate numbers appear.

Input:

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

Output:

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

Reminder: have a space, other places do not print excess symbols between two numbers

Sample code:

/**
    关于数组xv,yv,vv起的标记作用
    其思想其实也很简单,就是做到数独上面的格子能够和xv,yv,vv上的格子有个对应关系 
    感觉深搜基本上都会用到数组标记的技巧(用来回溯) 
*/ 
#include<cstdio>
char s[10][10]; //存储"棋盘"上的数据 
bool xv[10][10], yv[10][10], vv[10][10];    //用来标记行、列、3x3格子填过数的位置
bool f; 
void dfs(int x, int y) {
    
    if(f) {
        return;
    }
    
    if( x == 9 ) {      //x为9 说明所有的行都填数完毕 
        f = true;
        //所有数字都已经填完,输出填完之后的数独"棋盘" 
        for (int i = 0; i < 9; i ++) {
            for (int j = 0; j < 9; j ++) {
                
                if(j == 8) {
                    printf("%c\n",s[i][j]);
                } else {
                    printf("%c ",s[i][j]);
                }
                    
            }
        }
        return;
    }
    
    if( y == 9 ) {      //y为9说明填好一行 
        dfs(x + 1, 0);  //换一行继续填 
        return;
    }
    
    if(s[x][y] != '*') {
        dfs(x, y + 1);
        return;
    }
    
    for(int i = 1; i <= 9; i ++) {
    //printf("%d %d %d\n",x, y, i);
        //在符合条件的位置上填数
        if(!xv[x][i] && !yv[y][i] && !vv[x / 3 * 3 + y / 3][i]) {
            xv[x][i] = yv[y][i] = vv[x / 3 * 3 + y / 3][i] = true;    //已经填过的数在对应、列、3x3方格上做好标记
            s[x][y] = i + '0';    //填入数字
            dfs(x, y + 1);
            xv[x][i] = yv[y][i] = vv[x / 3 * 3 + y / 3][i] = false;    //取消填过的数(深搜到某一步发现当前解不符合条件时需要回溯上一个dfs(int x,int y),此时需要取消历史填数以便进行其他试探)
            s[x][y] = '*';
        }
    }
    
}
int main() {
    //输入一个原始的数独数据 
    for(int i = 0; i < 9; i ++ ) {
        for (int j = 0; j < 9; j ++) {
            
            scanf(" %c",&s[i][j]);  //" %c"留了一个空格是为了吃掉输入中的空格
             
            //将已经填好数字的位置 通过 xv yv vv数组做个标记 
            if(s[i][j] != '*') {    
                xv[i][s[i][j] - '0'] = true;
                yv[j][s[i][j] - '0'] = true;
                vv[i / 3 * 3 + j / 3][s[i][j] - '0'] = true;
            }
        }
    }
    dfs(0, 0);
    return 0;
}

Guess you like

Origin www.cnblogs.com/zhixiangshu/p/12300024.html