taozhenJ 2024-08-15 20:20 采纳率: 57.9%
浏览 6
已结题

数独(C++,函数)

数独是源自 18 世纪瑞士的一种数学游戏,它是一种运用纸、笔进行演算的逻辑游戏。

玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1−9,不重复。本题不要求你填数独,而是给你一个已经填好的数独,请你验证一下该数独是否正确(即满足每一行、每一列、每一个粗线宫内的数字均含1−9)。

小E觉得这个问题很简单,所以他偷偷交换了数独某两个宫内对应位置上的数字(也可能没换)。

现在,请你判断给出的数独是否可以通过交换或不换其中两个宫内的对应数字使得数独正确。

  • 写回答

3条回答 默认 最新

  • GISer Liu 2024-08-15 23:34
    关注

    该回答引用自GPT-deepseek, 由博主 GISer Liu 编写:

    好的,我们来详细分析并解决这个问题。

    问题分析

    用户需要验证一个9×9的数独是否正确,并且判断是否可以通过交换两个宫内的对应数字使得数独正确。数独的正确性要求每一行、每一列、每一个3×3的宫内的数字均含1-9,不重复。

    解决方案

    我们可以分两步来解决这个问题:

    1. 验证当前数独是否正确。
    2. 如果数独不正确,判断是否可以通过交换两个宫内的对应数字使得数独正确。

    详细步骤

    1. 验证数独是否正确

    我们需要检查每一行、每一列和每一个3×3的宫内的数字是否满足1-9不重复。

    2. 判断是否可以通过交换两个宫内的对应数字使得数独正确

    如果数独不正确,我们需要检查是否可以通过交换两个宫内的对应数字来修正数独。具体来说,我们可以尝试交换两个宫内的对应位置上的数字,然后再次验证数独是否正确。

    代码实现

    1. 验证数独是否正确

    #include <stdio.h>
    #include <stdbool.h>
    
    #define N 9
    
    // 检查一个数组是否包含1-9的所有数字
    bool checkArray(int arr[N]) {
        bool seen[N + 1] = {false};
        for (int i = 0; i < N; i++) {
            if (arr[i] < 1 || arr[i] > 9 || seen[arr[i]]) {
                return false;
            }
            seen[arr[i]] = true;
        }
        return true;
    }
    
    // 验证数独是否正确
    bool isValidSudoku(int board[N][N]) {
        // 检查每一行
        for (int i = 0; i < N; i++) {
            if (!checkArray(board[i])) {
                return false;
            }
        }
    
        // 检查每一列
        for (int j = 0; j < N; j++) {
            int column[N];
            for (int i = 0; i < N; i++) {
                column[i] = board[i][j];
            }
            if (!checkArray(column)) {
                return false;
            }
        }
    
        // 检查每一个3x3的宫
        for (int block = 0; block < N; block++) {
            int startRow = (block / 3) * 3;
            int startCol = (block % 3) * 3;
            int square[N];
            int index = 0;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    square[index++] = board[startRow + i][startCol + j];
                }
            }
            if (!checkArray(square)) {
                return false;
            }
        }
    
        return true;
    }
    

    2. 判断是否可以通过交换两个宫内的对应数字使得数独正确

    // 交换两个宫内的对应位置上的数字
    void swapCells(int board[N][N], int block1, int block2) {
        int startRow1 = (block1 / 3) * 3;
        int startCol1 = (block1 % 3) * 3;
        int startRow2 = (block2 / 3) * 3;
        int startCol2 = (block2 % 3) * 3;
    
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int temp = board[startRow1 + i][startCol1 + j];
                board[startRow1 + i][startCol1 + j] = board[startRow2 + i][startCol2 + j];
                board[startRow2 + i][startCol2 + j] = temp;
            }
        }
    }
    
    // 判断是否可以通过交换两个宫内的对应数字使得数独正确
    bool canFixSudoku(int board[N][N]) {
        if (isValidSudoku(board)) {
            return true;
        }
    
        for (int block1 = 0; block1 < N; block1++) {
            for (int block2 = block1 + 1; block2 < N; block2++) {
                swapCells(board, block1, block2);
                if (isValidSudoku(board)) {
                    return true;
                }
                swapCells(board, block1, block2); // 恢复原状
            }
        }
    
        return false;
    }
    

    完整代码

    #include <stdio.h>
    #include <stdbool.h>
    
    #define N 9
    
    // 检查一个数组是否包含1-9的所有数字
    bool checkArray(int arr[N]) {
        bool seen[N + 1] = {false};
        for (int i = 0; i < N; i++) {
            if (arr[i] < 1 || arr[i] > 9 || seen[arr[i]]) {
                return false;
            }
            seen[arr[i]] = true;
        }
        return true;
    }
    
    // 验证数独是否正确
    bool isValidSudoku(int board[N][N]) {
        // 检查每一行
        for (int i = 0; i < N; i++) {
            if (!checkArray(board[i])) {
                return false;
            }
        }
    
        // 检查每一列
        for (int j = 0; j < N; j++) {
            int column[N];
            for (int i = 0; i < N; i++) {
                column[i] = board[i][j];
            }
            if (!checkArray(column)) {
                return false;
            }
        }
    
        // 检查每一个3x3的宫
        for (int block = 0; block < N; block++) {
            int startRow = (block / 3) * 3;
            int startCol = (block % 3) * 3;
            int square[N];
            int index = 0;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    square[index++] = board[startRow + i][startCol + j];
                }
            }
            if (!checkArray(square)) {
                return false;
            }
        }
    
        return true;
    }
    
    // 交换两个宫内的对应位置上的数字
    void swapCells(int board[N][N], int block1, int block2) {
        int startRow1 = (block1 / 3) * 3;
        int startCol1 = (block1 % 3) * 3;
        int startRow2 = (block2 / 3) * 3;
        int startCol2 = (block2 % 3) * 3;
    
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int temp = board[startRow1 + i][startCol1 + j];
                board[startRow1 + i][startCol1 + j] = board[startRow2 + i][startCol2 + j];
                board[startRow2 + i][startCol2 + j] = temp;
            }
        }
    }
    
    // 判断是否可以通过交换两个宫内的对应数字使得数独正确
    bool canFixSudoku(int board[N][N]) {
        if (isValidSudoku(board)) {
            return true;
        }
    
        for (int block1 = 0; block1 < N; block1++) {
            for (int block2 = block1 + 1; block2 < N; block2++) {
                swapCells(board, block1, block2);
                if (isValidSudoku(board)) {
                    return true;
                }
                swapCells(board, block1, block2); // 恢复原状
            }
        }
    
        return false;
    }
    
    int main() {
        int board[N][N] = {
            {5, 3, 4, 6, 7, 8, 9, 1, 2},
            {6, 7, 2, 1, 9, 5, 3, 4, 8},
            {1, 9, 8, 3, 4, 2, 5, 6, 7},
            {8, 5, 9, 7, 6, 1, 4, 2, 3},
            {4, 2, 6, 8, 5, 3, 7, 9, 1},
            {7, 1, 3, 9, 2, 4, 8, 5, 6},
            {9, 6, 1, 5, 3, 7, 2, 8, 4},
            {2, 8, 7, 4, 1, 9, 6, 3, 5},
            {3, 4, 5, 2, 8, 6, 1, 7, 9}
        };
    
        if (canFixSudoku(board)) {
            printf("数独可以通过交换两个宫内的对应数字使得数独正确。\n");
        } else {
            printf("数独无法通过交换两个宫内的对应数字使得数独正确。\n");
        }
    
        return 0;
    }
    

    总结

    通过上述代码,我们可以验证一个数独是否正确,并且判断是否可以通过交换两个宫内的对应数字使得数独正确。代码中包含了详细的注释和步骤说明,确保用户可以理解和使用。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月15日
  • 已采纳回答 10月7日
  • 创建了问题 8月15日

悬赏问题

  • ¥15 Boost库编译出错。
  • ¥15 使用docker安装chemex后无法启动
  • ¥15 关于#vue.js#的问题:word excel和ppt预览问题语言-javascript)
  • ¥15 Apache显示系统错误3该如何解决?
  • ¥30 uniapp小程序苹果手机加载gif图片不显示动效?
  • ¥20 js怎么实现跨域问题
  • ¥15 C++dll二次开发,C#调用
  • ¥15 请教,如何使用C#加载本地摄像头进行逐帧推流
  • ¥15 Python easyocr无法顺利执行,如何解决?
  • ¥15 为什么会突然npm err!啊