HJ44 Sudoku(没做出来)

本文介绍了一个C语言实现的数独解决方案。代码包括了检查行、列和3x3宫格合法性的函数,以及递归旅行法填充空白单元格。通过示例展示了如何读取部分填充的数独盘面并输出完整解决方案。
描述
问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
入描述:
包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:
完整的9X9盘面数组

示例1
输入:
0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1
输出:
5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1
#include <stdio.h>
#include <string.h>

int judge_rc(int a[][9], int r, int c, int cur)
{
    int i;
    
    for(i=0; i<9; i++)
    {
        // 注意要过滤掉同一位置的点,否则必然在这条路上返回
        if(i!=c && a[r][i]==cur)
        {
            return 0;
        }
    }
    for(i=0; i<9; i++)
    {
        // 注意要过滤掉同一位置的点,否则必然在这条路上返回
        if(i!=r && a[i][c]==cur)
        {
            return 0;
        }
    }
    
    return 1;
}


int judge_3x3(int a[][9])
{
    int i, j, k, m;
    char b[10] = {0};
    
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            memset(b, 0, sizeof(b));
            for(k=3*i; k<3*i+3; k++)
            {
                for(m=3*j; m<3*j+3; m++)
                {
                    b[a[k][m]] = 1;
                }
            }
            for(k=1; k<10; k++)
            {
                if(b[k] == 0)
                {
                    return 0;
                }
            }
        }
    }
    return 1;
}
#if 1
// 注意二维数组地址的传参方式
int travel(int a[][9], int site)
{
    int i, j;
    
    if(site == 80)
    {
        if(a[8][8] == 0)
        {
            for(i=1; i<10; i++)
            {
                a[8][8] = i;
                if(judge_rc(a, 8, 8, i)==1 && judge_3x3(a)==1)
                {
                    return 1;
                }
            }
            // 此处一开始写成了 ==,导致查了一下午才查出来
            a[8][8] = 0;
            return 0;
        }
        else
        {
            return (judge_3x3(a));
        }
    }
    else
    {
        if(a[site/9][site%9] != 0)
        {
            return travel(a, site+1);
        }
        else
        {
            for(i=1; i<10; i++)
            {
                *(a[0]+site) = i;
                if(judge_rc(a, site/9, site%9, i)==1 && travel(a, site+1)==1)
                {
                    return 1;
                }
            }
            *(a[0]+site) = 0;
            return 0;
        }
    }
}
#else
int travel(int a[][9], int site)
{
    int i;
    
    if(a[site/9][site%9] == 0)
    {
        for(i=1; i<10; i++)
        {
            a[site/9][site%9] = i;
            if(judge_rc(a, site/9, site%9, i) == 1)
            {
                if(site==80 /*&& judge_3x3(a)==1*/)
                {
                    if(judge_3x3(a)==1)
                    return 1;
                }
                else
                {
                    if(travel(a, site+1) == 1)
                    {
                        return 1;
                    }
                }
            }
        }
        
        a[site/9][site%9] = 0;
        return 0;
    }
    else
    {
        if(site == 80)
        {
            return judge_3x3(a);
        }
        else
        {
            return travel(a, site+1);
        }
    }
}
#endif
int main(void)
{
    int a[9][9] = {0};
    int i, j;
    for(i=0; i<9; i++)
    {
        for(j=0; j<9; j++)
            scanf("%d", &a[i][j]);
    }
    travel(a, 0);
    //printf("%d\n", travel(a, 0));
    for(i=0; i<9; i++)
    {
        for(j=0; j<9; j++)
        {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

思路:每次插入一个值都判断所在行列是否符合,当到达最后一个元素师,判断每3x3个小方块是否符合条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值