C语言实现的数独解题程序

来源:互联网 发布:质谱软件 编辑:程序博客网 时间:2024/06/04 17:51

用最暴力的递归方式在所有可能的空间中寻找数独的解法。试了一下,不管多难的数独都能在1s内找到所有答案,所以也没有采取更智能的算法进行优化,如加入人的逻辑推理算法。

这里只是把一种最笨的方法分享出来,只是感叹现在的计算机运算能力太强大了。源码如下:


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

/*数独二维数组*/
int g_s[9][9] = {    
{0,4,0,7,0,0,0,0,0},
{9,2,0,0,0,0,6,0,7},
{8,3,0,0,0,5,4,0,0},
{0,1,0,0,0,3,0,0,0},
{0,0,0,2,0,1,0,0,0},
{0,0,0,5,0,0,0,4,0},
{0,0,4,9,0,0,0,7,1},
{3,0,5,0,0,0,0,9,4},
{0,0,0,0,0,8,0,6,0}
};

/*打印当前数独状态*/
int prt()
{
    int i = 0;
    int j = 0;
    for(i = 0;i < 9;i++)
    {
        for(j = 0;j < 9;j++)
        {
            printf("%d ",g_s[i][j]);
        }
        printf("\n");
    }

    getchar();
}

/*获取一个位置当前所有可能的解*/
int get_all_num(int i,int j,int a[9])
{
    int s[9] = {1,2,3,4,5,6,7,8,9};
    int row,col,k;

    /*删除当前行中已出现的值*/
    for(col = 0;col < 9;col++)
    {
        k = g_s[i][col];
        if(k != 0)
        {
            s[k-1] = 0;
        }
    }

    /*删除当前列中已出现的值*/
    for(row = 0;row < 9;row++)
    {
        k = g_s[row][j];
        if(k != 0)
        {
            s[k-1] = 0;
        }
    }

    /*删除当前九宫格中已出现的值*/
    row = (i/3)*3;
    col = (j/3)*3;
    for(i = row;i < (row+3);i++)
    {
        for(j = col;j < (col+3);j++)
        {
            k = g_s[i][j];
            if(k != 0)
            {
                s[k-1] = 0;
            }
        }
    }

    i = 0;
    for(k = 0;k < 9;k++)
    {
        if(s[k] != 0)
        {
            a[i] = s[k];
            i++;
        }
    }
    
    return i;
}

/*判断当前行是否合法*/
int check_row(int i,int num)
{
    int j = 0;
    for(j = 0;j < 9;j++)
    {
        if(g_s[i][j] == num)
        {
            return 0;
        }
    }
    
    return 1;
}

/*判断当前列是否合法*/
int check_col(int j,int num)
{
    int i = 0;
    for(i = 0;i < 9;i++)
    {
        if(g_s[i][j] == num)
        {
            return 0;
        }
    }

    return 1;
        
}

/*判断当前九宫格是否合法*/
int check_block(int i,int j,int num)
{
    int row = (i/3)*3;
    int col = (j/3)*3;
    int k = 0;
    int l = 0;
    
    for(k = row;k < (row+3);k++)
    {
        for(l = col;l < (col+3);l++)
        {
            if(g_s[k][l] == num)
            {
                return 0;
            }
        }
    }
    

    return 1;
}

/*尝试一个解*/
int try_one(int i,int j,int num)
{
    if(check_row(i,num) && check_col(j,num) &&
        check_block(i,j,num))
    {
        g_s[i][j] = num;
        //prt();
        return 1;
    }

    return 0;
}

/*获取下一个要填空的位置*/
int get_next(int *pi,int *pj)
{
    int i = *pi;
    int j = *pj;
    int r = i;
    int c = 0;
    j++;

    for(;r < 9;r++)
    {
        for(c = j;c < 9;c++)
        {
            if(g_s[r][c] == 0)
            {
                *pi = r;
                *pj = c;
                return;
            }
        }
        j = 0;
    }

    if(r == 9)
    {
        return 0;
    }

    *pi = r;
    *pj = c;
    return 1;

}

/*找到一个解*/
void finish()
{
    printf("\n find a solution: \n");
    prt();
}

/*处理一个位置*/
int do_one(int i,int j)
{
    int row = i;
    int col = j;
    int n = 0;
    int k = 0;
    int a[9] = {0};
    
    /*当前位置有解,下一个位置*/
    if(g_s[row][col] != 0)
    {
        /*获取下一个无解的位置*/
        if(get_next(&row,&col))
        {
            /*对一下个位置递归操作*/
            do_one(row,col);
        }
        /*都有解了,成功*/
        else
        {
            finish();
        }

        /*当前位置有解,直接回溯*/
        return;
    }

    /*当前位置无解*/
    else
    {
        /*获取当前位置的所有可能解*/
        n = get_all_num(i,j,a);
        
        for(k = 0;k < n;k++)
        {
            /*尝试所有可能的解,这里是重复操作,就不改了*/
            if(try_one(i,j,a[k]))
            {
                row = i;
                col = j;
                /*此位置找到合适的了,下一个*/
                if(get_next(&row,&col))
                {    
                    do_one(row,col);
                }
                /*当前位置已有解且没有下一个了,结束*/
                else
                {
                    finish();
                }
            }
        }

        /*要向前回溯,则这个位置找到的解无效,回溯前清0*/
        g_s[i][j] = 0;
        //prt();
        return;
    }

    
}

int main()
{
    do_one(0,0);

    return 0;

}


0 0
原创粉丝点击