用C语言求解数独

今天中午无聊之际,玩了下数独,玩了一把,速度很慢,于是想着,怎样用程序来解题呢,第一个想法就是暴力搜索,于是写了代码如下,暂时没有想到其他的算法,有更好算法的同学,欢迎一起交流。

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

int SolveCount = 0 ;        //! 解法计数

//! 需要求解的数独数据 0表示未知数,需要求解的值,不同的数独,修改此数组的值
int SudokuArr[9][9] =
{
    /*{0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,*/

    /*{0 , 1 , 0 , 3 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 4 , 0 , 2 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 8 , 5 , 0 , 0 } ,
    {0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,*/

    {0 , 0 , 4 , 2 , 5 , 0 , 0 , 0 , 0 } ,
    {0 , 0 , 1 , 0 , 0 , 4 , 9 , 0 , 0 } ,
    {9 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 0 , 3 , 1 , 0 , 0 , 0 } ,
    {0 , 0 , 0 , 9 , 0 , 2 , 0 , 0 , 0 } ,
    {3 , 0 , 9 , 0 , 8 , 0 , 0 , 7 , 0 } ,
    {0 , 1 , 0 , 0 , 0 , 6 , 0 , 0 , 0 } ,
    {0 , 5 , 0 , 0 , 0 , 7 , 0 , 6 , 0 } ,
    {6 , 9 , 0 , 0 , 0 , 3 , 0 , 0 , 0 } ,
} ;

//! 打印显示数独
void Display_Sudoku(void)
{
    int row , col ;
    for(row = 0 ; row < 9 ; ++ row)
    {
        for(col = 0 ; col < 9 ; ++ col)
            printf(" %d" , SudokuArr[row][col]) ;
        printf("\n") ;
    }
}

//! 寻找下一个需要填的空位
int Find_Next_Empty(int * pos)
{
    int row , col ;
    for(row = 0 ; row < 9 ; ++ row)
    {
        for(col = 0 ; col < 9 ; ++ col)
        {
            if(SudokuArr[row][col] == 0)
            {
                * pos = row * 9 + col ;
                return 1 ;
            }
        }
    }
    return 0 ;
}

//! 检查该位置的数字是否满足要求,1 满足 0 不满足
int Check_Sudoku(int pos , int num)
{
    int row = pos / 9 , col = pos % 9 , i , j , x , y ;

    //! 判断行重复
    for(i = 0 ; i < 9 ; ++ i)
    {
        if(SudokuArr[row][i] == num) return 0;
    }

    //! 判断列重复
    for(i = 0 ; i < 9 ; ++ i)
    {
        if(SudokuArr[i][col] == num) return 0;
    }

    //! 判断小九宫格重复
    x = col / 3 * 3 ; y = row / 3 * 3 ;
    for(i = 0 ; i < 3 ; ++ i)
    {
        for(j = 0 ; j < 3 ; ++ j)
        {
            if(SudokuArr[y + i][x + j] == num) return 0 ;
        }
    }

    return 1 ;  //! 无重复,满足要求
}

//! 求解数独
void Solve_Sudoku(void)
{
    int pos ;
    if(!Find_Next_Empty(&pos)) //! 判断是否填完
    {
        SolveCount ++ ;
        printf("Solution:  %d\n" , SolveCount) ;
        Display_Sudoku() ;
        getchar() ;            //! 按下Enter键获取下一个解法
    }
    else
    {
        int num = 1 ;
        for( ; num < 10 ; ++ num)
        {
            if(Check_Sudoku(pos , num)) //! 判断该值是否满足要求
            {
                int row = pos / 9 , col = pos % 9 ;
                SudokuArr[row][col] = num ;
                Solve_Sudoku() ;
                SudokuArr[row][col] = 0 ;
            }
        }
    }
}

int main()
{
    Solve_Sudoku() ;
    return 0;
}

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值