第19届PTA天梯赛 L2——九宫格

        题意比较容易理解,简单复述一下,就是给定n个9*9的方格,我需要你去判断九行九列是否都满足 1 到 9 这九个数字中的每个数字都只出现一次,还有一个条件是9*9我们可以分成9个3*3的——正方形宫位(题目这样称) 就是下面这张图

分成九个3*3的小方格,要求还是满足 1 到 9 这九个数字中的每个数字都只出现一次。

(注意有个坑点,测试数据可能出现大于9的或者小于1的,所以我们需要注意一下)

我是直接创建了一个二维数组,jiu[10][10],因为我想从下标1开始

接着赋值矩阵即可,我们在输入的时候可以先去判断一下行是否满足条件,后续就不用判断了

        bool pl=true;
        for(int i=1;i<=9;i++)
        {
            set<int> s;
            for(int j=1;j<=9;j++)
            {
                cin>>jiu[i][j];
                if(jiu[i][j]<1||jiu[i][j]>9)
                    pl=false;
                s.insert(jiu[i][j]);
            }
            if(s.size()!=9)
                pl=false;
        }

判断方法是定义一个set集合(可以去除重复元素),我们只需要最后判断一下大小是不是9,如果不是,令pl的false,后续直接输出0(不符合条件)即可。注意里面还有一个判断是否是1~9之间的数字,没有注意这一个坑点会扣分的~

如果他小子侥幸过了第一个判断,我们就要更严格去强调他的列和9个3*3正方形宫位了。

定义一个check()函数具体代码如下:

        if(pl&&check())
            cout<<"1\n";
        else
            cout<<"0\n";

//注意使用&& 如果pl都是false了我压根不会去调用check函数,省时间~  我直接输出0就好了呀;


int dir1[3][2]={1,3,4,6,7,9};   //简化代码长度的关键!
int dir2[3][2]={1,3,4,6,7,9};

bool check()
{
    for (int j = 1; j <= 9; j++)
    {
        set<int> s;
        for (int i = 1; i <= 9; i++)
            s.insert(jiu[i][j]);
        if (s.size() != 9)
            return false;
    }
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        {
            set<int> s;
            for(int p=dir1[i][0];p<=dir1[i][1];p++)
                for(int q=dir2[j][0];q<=dir2[j][1];q++)
                    s.insert(jiu[p][q]);
            if(s.size()!=9)
                return false;
        }
    return true;
}

注意看我们定义了两个dir数组,等等我再来解释一下这两个是干嘛的。

先看check的前面部分,是不是很熟悉,这不就是前面判断 行 是否满足条件的代码嘛,改变了一下i j的位置而已,就是判断各列满不满足条件。如果不满足,我直接返回false 不然就得乖乖继续往下判断咯

接下来就需要用到dir数组; 如果不使用它,代码会变得非常长,而且代码重复率极高,一看就不专业,我当然还是追求专业的~

其实呢作用就是去判断9和3*3是否满足条件所需要的。我们如果用脑子模拟一下的话,第一次我去判断        i从1到3 ;j从1到3   第二次  i从1到3;j从4到6  第三次  i从1到3;j从7到9   每次都是一样的代码,就是i j不同,这么一个一个模拟,我就得写9个简直一模一样的代码,这样不好,不好(虽然考试的我确实是这么写的哈哈哈,这个思想我比赛没想浪费时间思考,毕竟对于我也得思考几分钟,用几个脑细胞想想这样对不对,是不是都包括全了,所以就没写。不过我一下来就复现了一下,没问题,我能想出来)

我们去看一下dir数组 分别是3*2的二维矩阵对吧,分别是1 3 4 6 7 9,正好是i j的起始和末端位置,接下来两个for循环遍历就行,过程中只要有一个小正方形宫位不满足,反手就是一个剪枝(return  false)就行。

别忘了最后的return true 要是都满足,咱们也不能忘了返回一个true,这样就能输出1了,否则还是输出0。

完毕!附上完整代码

#include<iostream>
#include<set>
#include<bits/stdc++.h>
using namespace std;
int jiu[10][10];
int dir1[3][2]={1,3,4,6,7,9};
int dir2[3][2]={1,3,4,6,7,9};
bool check()
{
    for (int j = 1; j <= 9; j++)
    {
        set<int> s;
        for (int i = 1; i <= 9; i++)
            s.insert(jiu[i][j]);
        if (s.size() != 9)
            return false;
    }
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        {
            set<int> s;
            for(int p=dir1[i][0];p<=dir1[i][1];p++)
                for(int q=dir2[j][0];q<=dir2[j][1];q++)
                    s.insert(jiu[p][q]);
            if(s.size()!=9)
                return false;
        }
    return true;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        bool pl=true;
        for(int i=1;i<=9;i++)
        {
            set<int> s;
            for(int j=1;j<=9;j++)
            {
                cin>>jiu[i][j];
                if(jiu[i][j]<1||jiu[i][j]>9)
                    pl=false;
                s.insert(jiu[i][j]);
            }
            if(s.size()!=9)
                pl=false;
        }
        if(pl&&check())
            cout<<"1\n";
        else
            cout<<"0\n";
    }
    return 0;
}

 大家不懂多多评论区交流,互相请教互相帮助,没准别人一句话就点通你(亲身经历)

 期待和大家共同加油,希望大家不断进步!

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值