数独合理吗(九宫格)


链接:https://ac.nowcoder.com/acm/contest/19306/1025
来源:牛客网

题目描述

众所周知,数独是一款简单上手(划掉)且极易打发时间的游戏,
fishfloss喜欢玩数独,虽然自己很菜。
数独的具体规则是这样的:
需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,
并满足每一行、每一列、每一宫(3x3)内的数字均含1-9并不重复
例如 :
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
就是一个合法的数独的解

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 4
则不是
那么下面给出数独盘面,来判断一下它是否是数独的合法解吧

输入描述

输入共9行,每行9个数,代表数独盘面

输出描述

一行,如果输入是数独的合法解,则输出YES
反之输出NO

示例一

输入

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

输出

YES

示例二

输入

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

输出

NO

说明

对于宫9,行9及列9,显然有重复的4,故不满足合法解

题目分析及解题思路

本题主要考察对数独的理解和对数组的运用。判断数独是否合理,需要判断每行每列每宫的数字是否为1~9且不重复。可以用九个数和为45来判断,也可以直接判断当前的数是否与之前的数相等。

解决方案

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i,j,arr[11][11];
    int m,n,k,x;
    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
        {
            cin>>arr[i][j];
            //判断每行当前这个数与前面输入的数是否重复
            for(m=0;m<j;m++)
                if(arr[i][m]==arr[i][j])
                {//重复则输出NO
                    cout<<"NO";
                    return 0;
                }
        }
    }
    for(j=0;j<9;j++)
    {
        for(i=0;i<9;i++)
        {//判断每列当前这个数与前面输入的数是否重复
            for(n=0;n<i;n++)
                if(arr[n][j]==arr[i][j])
                {//重复则输出NO
                    cout<<"NO";
                    return 0;
                }
        }
    }
    for(i=0;i<9;i+=3)
    {
        for(j=0;j<9;)
        {//判断当前这个宫(3*3)是否有重复数字
            int sum=0;
            for(k=i;k<i+3;k++)
            {
                for(x=j;x<j+3;x++)
                {//这里用的是宫中所有数相加是否得45来判断
                    sum+=arr[k][x];
                }
            }
            if(sum==45)
                j+=3;//等于45判断下一个宫
            else
                break;//不等于45,结束当前循环
        }
        if(j==9)//说明在以上操作中没有执行break,即以上已判断的宫都合理
            i+=3;//进行下一行宫的判断
        else
            break;//以上判断的宫存在不合理,退出当前循环
    }
    if(i<9)//说明上一条break被执行
    {
        cout<<"NO";
        return 0;
    }
    //因为以上判断中都有return 0语句,所以不满足以上if语句的都为YES
    cout<<"YES";
    return 0;
}

好的,九宫格数独问题是一个经典的回溯算法应用。回溯算法的核心思想是在搜索过程中遇到无法满足条件的情况时,返回上一个状态并尝试其他路径,直到找到满足条件的解。 对于九宫格数独问题,我们需要在9x9的数独棋盘上填入1~9的数字,满足每行、每列、每个3x3的小九宫格内都不重复出现相同数字。我们可以使用深度优先搜索的方法,在每个空格中尝试填入数字,然后继续搜索下一个空格,直到所有的空格都被填满或者搜索到无解状态,此时需要回溯到上一个状态继续尝试其他数字。 下面是一个简单九宫格数独回溯算法的伪代码实现: ``` function solveSudoku(board): if board is None or len(board) == 0: return False # 遍历数独棋盘,找到第一个空格 for i in range(9): for j in range(9): if board[i][j] == '.': # 尝试填入1~9的数字 for k in range(1, 10): if isValid(board, i, j, str(k)): board[i][j] = str(k) # 递归搜索下一个空格 if solveSudoku(board): return True # 回溯到上一个状态 board[i][j] = '.' return False return True # 判断填入的数字是否合法 def isValid(board, row, col, num): for i in range(9): if board[row][i] == num: return False if board[i][col] == num: return False if board[(row//3)*3 + i//3][(col//3)*3 + i%3] == num: return False return True ``` 在上述代码中,我们首先遍历数独棋盘,找到第一个空格,然后尝试填入1~9的数字,判断填入的数字是否合法,如果合法就递归搜索下一个空格,如果搜索到无解状态就回溯到上一个状态,继续尝试其他数字,直到所有的空格都被填满或者搜索到无解状态。其中isValid函数用于判断填入的数字是否合法,需要判断当前行、列、小九宫格是否已经出现该数字。 希望这个回答能够解决你的问题。如果还有其他疑问,欢迎再次提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值