数独求解----回溯递归,无脑枚举版

本文介绍了一种使用回溯递归算法解决数独问题的方法。程序通过读取sudo_input文件来设置数独游戏,并通过无脑枚举进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


#define LENGTH 9


int answer = 0;


void printSudo(int array[][LENGTH]) {
    printf("\n\n");
    int i, j;
    for (i = 0; i < LENGTH; i++) {
        if ((i + 1) % 3 == 0)
            printf("\n\n");
        for (j = 0; j< LENGTH; j++) {
            if ((j + 1) % 3 == 0)
                printf("\t");
            printf("%d  ", array[i][j]);
        }
        printf("\n");
    }
    exit(0);
}
void initSudoArray(int array[][LENGTH]) {
    int i, j;
    FILE *fp;

    if ((fp = fopen("sudo_input", "r")) == NULL) {
        printf("File open failed !\n");
        exit(-1);
    }

    for (i = 0; i < LENGTH; i++) {
        for (j = 0; j < LENGTH; j++) {
            fscanf(fp, "%d", &array[i][j]);
        }
    }
    
    fclose(fp);
}


int checkSudo(int array[][LENGTH], int i, int j, int testVal) {
    int row, col;
    printf("checkSudo for [%d][%d] testVal = %d\n", i, j, testVal);

    // fixed to col j, check for the rows
    for (row = 0; row < LENGTH; row++) {
        printf("check for rows! [%d][%d]  = %d\n", row, j, array[row][j]);
        if (array[row][j] == testVal)
            return 0;
    }


    // fixed to row i, check for cols
    for (col = 0; col < LENGTH; col++) {
        printf("check for cols! [%d][%d] = %d\n", i, col, array[i][col]);
        if (array[i][col] == testVal)
            return 0;
    }


    //check for the sub-square
    int row_subSquare = (i / 3) * 3;
    int col_subSquare = (j / 3) * 3;


    printf("[%d][%d]\n", row, col);
    for (row = row_subSquare; row < row_subSquare + 3; row++) {
        for (col = col_subSquare; col < col_subSquare + 3; col++) {
            printf("check for sub-square! [%d][%d] = %d\n", row, col, array[row][col]);
            if (array[row][col] == testVal)
                return 0;
        }
    }


    return 1;    
}


// length is the plane index of the sudo array
void sudo_solve(int array[][LENGTH], int length) {
    // i for rows, j for cols
    int i, j;


    int testVal;
    int tempArray[LENGTH][LENGTH];


    //dump the array to tempArray
    for (i = 0; i < LENGTH; i++) {
        for (j = 0; j < LENGTH; j++)
            tempArray[i][j] = array[i][j];
    }


    i = length / LENGTH;
    j = length % LENGTH;


    printf("array[%d][%d] = %d", i, j, array[i][j]);
    if (array[i][j] != 0) {
    // there is a val in the slot array[i][j]
        if (length == 80)
            printSudo(tempArray);
        else
            sudo_solve(tempArray, length + 1);
    } else {
    // there is no val in the slot array[i][j]
        for (testVal = 1; testVal <= LENGTH; testVal++) {
            if (checkSudo(tempArray, i, j, testVal) != 0) {

                tempArray[i][j] = testVal;

                if (length == 80)
                    printSudo(tempArray);
                else 
                    sudo_solve(tempArray, length + 1);
                
                tempArray[i][j] = 0;
            }
        }
    }
}


int main(void) {


    int array[LENGTH][LENGTH];
    initSudoArray(array);

    sudo_solve(array, 0);

    if (answer == 0)
        printf("There is no answer for this sudo!");

    return 0; 


}

程序会去读一个 sudo_input文件来初始化这个sudo游戏,sudo_input文件型如


8    0    0      0    0    0      0    0    0

0    0    3      6    0    0      0    0    0

0    7    0      0    9    0      2    0    0


0    5    0      0    0    7      0    0    0

0    0    0      0    4    5      7    0    0

0    0    0      1    0    0      0    3    0


0    0    1      0    0    0      0    6    8

0    0    8      5    0    0      0    1    0

0    9    0      0    0    0      4    0    0 


注意下面的代码就是回溯递归求解


// there is no val in the slot array[i][j]
        for (testVal = 1; testVal <= LENGTH; testVal++) {
            if (checkSudo(tempArray, i, j, testVal) != 0) {

                tempArray[i][j] = testVal;

                if (length == 80)
                    printSudo(tempArray);
                else 
                    sudo_solve(tempArray, length + 1);
                
                tempArray[i][j] = 0;
            }
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值