Problem A: 数独验证

Problem A: 数独验证

[Creator : ]
Time Limit : 1.000 sec  Memory Limit : 128 MiB

Description

数独是一种智力游戏。给定 lns="http://www.w3.org/1998/Math/MathML">9×9 个整数构成的矩阵,请验证这些整数的排列方式是否符合数独的条件。

一个合法的数独要求矩阵在每一行、每一列、每个宫都含有 lns="http://www.w3.org/1998/Math/MathML">1 到 lns="http://www.w3.org/1998/Math/MathML">9 的全部数字。所谓宫是指矩阵前三行、中三行、后三行与前三列、中三列、后三列组成的九个 lns="http://www.w3.org/1998/Math/MathML">3×3 的小矩阵。

提示:这是一个验证数独有效性的C++程序。我将分别检查每一行、每一列和每个3x3宫格是否包含1到9的所有数字。

  1. 读取输入:将9x9的数独矩阵读入二维数组

  2. 检查行:对每一行,检查1-9每个数字是否只出现一次

  3. 检查列:对每一列,检查1-9每个数字是否只出现一次

  4. 检查宫格:对每个3x3宫格,检查1-9每个数字是否只出现一次

  5. 输出结果:如果所有检查都通过,输出"Valid",否则输出"Invalid"

    #include <iostream>
    using namespace std;
    
    int main() {
        // 定义9x9的数独数组
        int sudoku[9][9];
        
        // 读取输入:循环读取9行,每行9个数字
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                cin >> sudoku[i][j];  // 将输入的数字存入数组
            }
        }
        
        // 标记数独是否有效,初始假设为有效
        bool valid = true;
        
        // ========== 第一步:检查每一行 ==========
        for (int i = 0; i < 9 && valid; i++) {  // 遍历每一行
            // seen数组记录数字1-9是否出现过,初始都为false
            // seen[1]到seen[9]分别对应数字1到9
            bool seen[10] = {false};
            
            for (int j = 0; j < 9; j++) {  // 遍历当前行的每一列
                int num = sudoku[i][j];    // 获取当前位置的数字
                
                // 如果这个数字已经在这一行中出现过
                if (seen[num]) {
                    valid = false;  // 数独无效
                    break;          // 跳出内层循环
                }
                
                // 标记这个数字已经出现过
                seen[num] = true;
            }
        }
        
        // ========== 第二步:检查每一列 ==========
        // 只有当行检查通过后才继续检查列
        if (valid) {
            for (int j = 0; j < 9; j++) {  // 遍历每一列
                bool seen[10] = {false};   // 重置标记数组
                
                for (int i = 0; i < 9; i++) {  // 遍历当前列的每一行
                    int num = sudoku[i][j];    // 获取当前位置的数字
                    
                    // 如果这个数字已经在这一列中出现过
                    if (seen[num]) {
                        valid = false;  // 数独无效
                        break;          // 跳出内层循环
                    }
                    
                    // 标记这个数字已经出现过
                    seen[num] = true;
                }
                
                // 如果已经发现无效,跳出外层循环
                if (!valid) break;
            }
        }
        
        // ========== 第三步:检查每个3x3宫格 ==========
        // 只有当行和列检查都通过后才继续检查宫格
        if (valid) {
            // 一共有9个宫格,编号0-8
            for (int block = 0; block < 9; block++) {
                // 计算当前宫格的起始行和起始列
                // block/3 得到宫格的行索引(0,1,2),乘以3得到实际起始行
                // block%3 得到宫格的列索引(0,1,2),乘以3得到实际起始列
                int startRow = (block / 3) * 3;   // 起始行:0,0,0,3,3,3,6,6,6
                int startCol = (block % 3) * 3;   // 起始列:0,3,6,0,3,6,0,3,6
                
                bool seen[10] = {false};  // 重置标记数组
                
                // 遍历当前3x3宫格内的所有格子
                for (int i = 0; i < 3; i++) {        // 行偏移 0,1,2
                    for (int j = 0; j < 3; j++) {    // 列偏移 0,1,2
                        // 计算实际位置:起始行+行偏移,起始列+列偏移
                        int num = sudoku[startRow + i][startCol + j];
                        
                        // 如果这个数字已经在这个宫格中出现过
                        if (seen[num]) {
                            valid = false;  // 数独无效
                            break;          // 跳出内层循环
                        }
                        
                        // 标记这个数字已经出现过
                        seen[num] = true;
                    }
                    // 如果已经发现无效,跳出中层循环
                    if (!valid) break;
                }
                // 如果已经发现无效,跳出外层循环
                if (!valid) break;
            }
        }
        
        // ========== 第四步:输出结果 ==========
        if (valid) {
            cout << "Valid" << endl;    // 所有检查都通过,输出Valid
        } else {
            cout << "Invalid" << endl;  // 有任何检查不通过,输出Invalid
        }
        
        return 0;
    }

Input

九行整数:每行九个数字表示一个矩阵。

  • 保证输入的每个数字均为 lns="http://www.w3.org/1998/Math/MathML">1 到 lns="http://www.w3.org/1998/Math/MathML">9 的整数。




Output

若满足数独条件,输出 Valid,否则输出 Invalid

Sample Input Copy

8 4 5 9 3 1 6 2 7  
9 1 6 5 2 7 8 3 4  
7 3 2 6 4 8 9 5 1  
5 7 8 4 9 3 2 1 6  
2 6 1 8 7 5 3 4 9  
4 9 3 2 1 6 5 7 8  
6 8 7 1 5 2 4 9 3  
3 5 9 7 6 4 1 8 2  
1 2 4 3 8 9 7 6 5 

Sample Output Copy

Valid