zoukankan      html  css  js  c++  java
  • 数独检查

    数独是一种流行的单人游戏。

    目标是用数字填充9x9矩阵,使每列,每行和所有9个非重叠的3x3子矩阵包含从1到9的所有数字。

    每个9x9矩阵在游戏开始时都会有部分数字已经给出,通常有一个独特的解决方案。

    1.png

    2.png

    给定完成的N2N2数独矩阵,你的任务是确定它是否是有效的解决方案。

    有效的解决方案必须满足以下条件:

    • 每行包含从1到N2的每个数字,每个数字一次。
    • 每列包含从1到N2的每个数字,每个数字一次。
    • N2N2矩阵划分为N2个非重叠NN子矩阵。 每个子矩阵包含从1到N2的每个数字,每个数字一次。

    你无需担心问题的唯一性,只需检查给定矩阵是否是有效的解决方案即可。

    输入格式

    第一行包含整数T,表示共有T组测试数据。

    每组数据第一行包含整数N。

    接下来N2行,每行包含N2个数字(均不超过1000),用来描述完整的数独矩阵。

    输出格式

    每组数据输出一个结果,每个结果占一行。

    结果表示为“Case #x: y”,其中x是组别编号(从1开始),如果给定矩阵是有效方案则y是Yes,否则y是No。

    数据范围

    1T100,
    3N6

    输入样例:

    3
    3
    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
    3
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    3
    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 999 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
    

    输出样例:

    Case #1: Yes
    Case #2: No
    Case #3: No



    对矩阵的检查,要从行、列、九宫格进行判断,因此我们需要建立三个方法分别检查行、列以及九宫格。
    不管是检查哪一个部分,原理都是相同的,我采用的方法是创建一个st数组,将已经出现的数作为下标对其
    所属的数组元素进行染色,比如一个3*3的九宫格,第一行的数据为 1、3、2,那么st[1] st[3] st[2]将分别进行自加操作.

    最后对st数组进行遍历,当st[i]==0或者st[i]>1的时候,说明该数未出现或者出现次数大于1次,那么我们直接判断这个九宫格不符合要求

    AC代码:
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N = 40;
    int a[N][N];
    int t,n,m;
    int st[40];
    
    inline bool check_row(){  //检查行 
        for(int i = 0;i<m;++i){
            memset(st,0,sizeof st);   //每次对新一行进行遍历时,都需要重新对st数组进行初始化 
            for(int j = 0;j<m;++j){
                int t = a[i][j];
                if(t<1 || t>m) return 0; //当t不在1-m之间时,不符合要求,直接return 0 ; 
                st[t]++;
            }
            for(int i = 1;i<=m;++i){  //遍历st数组 
                if(st[i]==0 || st[i]>1) return 0;
            }
        } 
        return 1;
    }
    
    inline bool check_col(){  //检查列 
        for(int i = 0;i<m;++i){
            memset(st,0,sizeof st);
            for(int j = 0;j<m;++j){
                int t = a[j][i];
                if(t<1 || t>m) return 0;
                st[t]++;
            }
            for(int i = 1;i<=m;++i){
                if(st[i]==0 || st[i]>1) return 0;
                } 
        }
        return 1;
    }
    
    inline bool check(){    //检查九宫格 
        for(int i = 0;i<m;i+=n){    
            for(int j = 0;j<m;j+=n){
            memset(st,0,sizeof st);
                for(int dx = 0;dx<n;++dx){
                    for(int dy = 0;dy<n;++dy){
                    int t = a[i+dx][j+dy];
                    if(t<1 || t>m) return 0;
                    st[t]++;
                    }
                }
            for(int i = 1;i<=m;++i){
                if(st[i]==0 || st[i]>1) return 0;
                    } 
            }
        }
        return 1;
    }
    
    int main()
    {
        cin>>t;
        for(int k = 1;k<=t;++k){
            cin>>n;
            m = n*n;
            for(int i = 0;i<m;++i){
                for(int j = 0;j<m;++j){
                    cin>>a[i][j];
                }
            }
            if(check_row() && check_col() && check()){
                printf("Case #%d: Yes
    ",k);
            }
            else printf("Case #%d: No
    ",k);
        }
        return 0;
    }


  • 相关阅读:
    [CTF隐写]png中CRC检验错误的分析
    Bugku
    Bugku
    【CTF 攻略】CTF比赛中关于zip的总结
    sqlserver中利用Tran_sql把逗号分隔的字符串拆成临时表
    H5摇一摇遇到的问题
    C# MVC 微信支付之微信模板消息推送
    各种大型网站技术架构
    ORM框架详解
    显示实现接口
  • 原文地址:https://www.cnblogs.com/ssfannnnn/p/14389713.html
Copyright © 2011-2022 走看看