数独(c++ dfs实现)

数独概念,思路,解法思路,C++code

该博客整体代码的思路十分的清晰,值得借鉴!
上述博客当中的代码dfs知识输出的一种数组的答案,如果该数独有多中解法的话,只需将dfs的代码简单改动即可(如下):

void dfs(int row,int col)
{
    if (row>9)  //如果行超出9行,直接输出
    {
        for (int i=1; i<=9; i++)
        {
            for (int j=1; j<=9; j++)
            {
                printf("%d",a[i][j]); (j == 9)? cout << "": cout <<" ";
            }
            printf("\n");
        }
        cout << "***************************************\n";
        //exit(0);// 经参数返回给操作系统,0 表示正常结束,非零表示不正常结束。
        return ;
    }

    if (a[row][col]==0)  //如果没有填数字
    {
        for (int i=1; i<=9; i++)
        {
            if (is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i))  //如果行列九宫格不重复
            {
                a[row][col]=i;//填充数字
                dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);//继续搜索
                a[row][col]=0;//重新置为0
            }
        }
        //a[row][col]=0;//重新置为0
    }
    else  //如果已经填了,继续搜索
    {
        dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);
    }
}

整体代码如下:

#include 
using namespace std;

int a[10][10];//存储数字

int is_row_col_repeat(int row,int col,int num) //判断行列是否重复
{
    //判断行是否重复
    for (int i=1; i<=9; i++)
    {
        if (a[row][i]==num)
        {
            return 0;//行重复,返回0
        }
    }
    //判断列是否重复
    for (int i=1; i<=9; i++)
    {
        if (a[i][col]==num)
        {
            return 0;//列重复,返回0
        }
    }
    return 1;//行列不重复,返回1
}
int check_row_range(int row) //判断行的范围
{
    if (row>=1 && row<=3)
    {
        return 1;
    }
    else if(row>=4&&row<=6)
    {
        return 4;
    }
    else
    {
        return 7;
    }
}
int check_col_range(int col) //判断列的范围
{
    if(col>=1&&col<=3)
    {
        return 1;
    }
    else if (col>=4&&col<=6)
    {
        return 4;
    }
    else
    {
        return 7;
    }
}
int is_block_repeat(int row,int col,int num) //判断同色九宫格是否重复
{
    int x,y;
    x=check_row_range(row);
    y=check_col_range(col);
    for (int i=x; i<=x+2; i++)
    {
        for (int j=y; j<=y+2; j++)
        {
            if (a[i][j]==num)
            {
                return 0;//重复,返回0
            }
        }
    }
    return 1;//不重复,返回1
}

void dfs(int row,int col)
{
    if (row>9)  //如果行超出9行,直接输出
    {
        for (int i=1; i<=9; i++)
        {
            for (int j=1; j<=9; j++)
            {
                printf("%d",a[i][j]); (j == 9)? cout << "": cout <<" ";
            }
            printf("\n");
        }
        cout << "***************************************\n";
        //exit(0);
        return ;
    }

    if (a[row][col]==0)  //如果没有填数字
    {
        for (int i=1; i<=9; i++)
        {
            if (is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i))  //如果行列九宫格不重复
            {
                a[row][col]=i;//填充数字
                dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);//继续搜索
                a[row][col]=0;//重新置为0
            }
        }
        //a[row][col]=0;//重新置为0
    }
    else  //如果已经填了,继续搜索
    {
        dfs(row+(col+1)/10, (col <= 8)? col+1 : 1);
    }
}
int main(int argc, char *argv[])
{
    string s;
    for(int i=1; i<=9; i++)
    {
        cin >> s;//输入字符串
        for(int j=1; j<=9; j++)
        {
            char ss=s.at(j-1);//取s的第j-1的字符
            a[i][j]=ss-'0';//将ss转化为整数
        }
    }
    dfs(1,1);
    return 0;
}

上述代码看着挺长的,我试着压缩了一下,感觉没有那么难看,而且也没有那么长了

#include 
using namespace std;

const int N = 10;
int a[N][N];

int is_row_col_repeat(int row, int col, int num)
{
    for(int i = 1; i <= 9; i++)
        if(a[row][i] == num || a[i][col] == num)
            return 0;
    return 1;
}

int check_row_range(int row)
{
    if(row >= 1 && row <= 3)
        return 1;
    else if(row >= 4 && row <= 6)
        return 4;
    else
        return 7;
}

int check_col_range(int col)
{
    if(col >= 1 && col <= 3)
        return 1;
    else if(col >= 4 && col <= 6)
        return 4;
    else
        return 7;
}

int is_block_repeat(int row, int col, int num)
{
    int x = check_row_range(row);
    int y = check_col_range(col);
    for(int i = x; i <= x+2; i++)
        for(int j = y; j <= y+2; j++)
            if(a[i][j] == num)
                return 0;
    return 1;
}

void output()
{
    for(int i = 1; i <= 9; i++)
        for(int j = 1; j <= 9; j++)
            cout << a[i][j], (j <= 8)? printf(" "): putchar('\n');
    printf("************************\n");
}

void dfs(int row, int col)
{
    if(row > 9) output(), exit(0);

    if(a[row][col] == 0)
        for(int i = 1; i <= 9; i++)
            if(is_row_col_repeat(row, col, i) && is_block_repeat(row, col, i))
            {
                a[row][col] = i;
                dfs(row + (col+1) / 10, (col <= 8)? col+1 : 1);
                a[row][col] = 0;
            }
    if(a[row][col] != 0) dfs( row + (col+1) / 10, (col <= 8)? col+1 : 1 );
}

int main()
{
    string s;

    for(int i = 1; i <= 9; i++)
    {
        cin >> s;
        for(int j = 1; j <= 9; j++)
        {
            char ss = s.at(j - 1);
            a[i][j] = ss - '0';
        }
    }

    dfs(1, 1);

    return 0;
}

你可能感兴趣的:(搜索)