个人项目——生成数独并解数独【解数独篇】

解数独我并没有想到什么特别好的办法,所以就直接爆搜了23333

基本思路就是一个DFS的过程,用plate[9][9]数组代表整个九宫格,从0~80依次编号,则第x个数在数组中的位置是plate[x/9][x%9],然后只需判断这个位置是不是空,如果是空则放置某个数,若该数合法则递归下一层,x = x+1;若该数不为空则直接递归下一层x = x+1。

注意在退出上一层递归时要将该位置数字“清零”,以免影响下一次放置。

下面附上解数独部分的代码(文件输出后续实现,此处暂用格式输出):

bool check(int x, int m, int n)//检查是否合法
{
    //
    for (int i = 0; i < 9; i++)
        if (plate[m][i] == x) return false;
    //
    for (int i = 0; i < 9; i++)
        if (plate[i][n] == x) return false;
    //同一九宫格
    int begin_i = m / 3 * 3;
    int begin_j = n / 3 * 3;
    for (int i = begin_i; i < begin_i + 3; i++)
        for (int j = begin_j; j < begin_j + 3; j++)
            if (plate[i][j] == x) return false;
    return true;
}

void solve(int count)//递归解数独
{
    if (flag) return;
    if (count == 81)
    {
        flag = true;
        for (int i = 0; i < 9; i++)
        {
            printf("%d", plate[i][0]);
            for (int j = 1; j < 9; j++)
                printf(" %d", plate[i][j]);
            printf("\n");
        }
        return;
    }
    int m = count / 9;
    int n = count % 9;
    if (plate[m][n] == 0)
    {
        for(int i = 1; i <= 9; i ++)
            if (check(i, m, n))
            {
                plate[m][n] = i;
                solve(count + 1);
            }
        plate[m][n] = 0;
    }
    else solve(count + 1);
}

关于解数独效率的问题,如果项目大致写完还有剩余时间我会继续优化。

 

4.11更新 【改为文件输出】

bool check(int x, int m, int n)
{
    for (int i = 0; i < 9; i++)
        if (plate[m][i] == x) return false;
    for (int i = 0; i < 9; i++)
        if (plate[i][n] == x) return false;
    int begin_i = m / 3 * 3;
    int begin_j = n / 3 * 3;
    for (int i = begin_i; i < begin_i + 3; i++)
        for (int j = begin_j; j < begin_j + 3; j++)
            if (plate[i][j] == x) return false;
    return true;
}

void solve(int count)
{
    if (flag) return;
    if (count == 81)
    {
        flag = true;
        for (int i = 0; i < 9; i++)
        {
            fputc(plate[i][0]+ '0', output_solve);
            for (int j = 1; j < 9; j++)
            {
                fputc(' ', output_solve);
                fputc(plate[i][j]+ '0', output_solve);
            }
            fputc('\n', output_solve);
        }
        fputc('\n', output_solve);
        return;
    }
    int m = count / 9;
    int n = count % 9;
    if (plate[m][n] == 0)
    {
        for(int i = 1; i <= 9; i ++)
            if (check(i, m, n))
            {
                plate[m][n] = i;
                solve(count + 1);
            }
        plate[m][n] = 0;
    }
    else solve(count + 1);
}

 

posted @ 2018-04-09 15:59  ---(´・_・`)---  阅读(273)  评论(0编辑  收藏  举报