给数独验证题目编写测试代码

一、题目介绍:

数独是一种填数游戏,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。

每个数独有唯一解。下图是一个数独填数后的解(黑色数字是已知数字,绿色数字是填数数字)。

输入填数后的9×9盘面,写函数判断其是否是解,返回1或0。

原题目地址为 https://blog.csdn.net/2203_75720729/article/details/128789015

输入要求:

测试次数

每组测试数据是1个9*9的数字阵(元素值:1~9)

输出要求:

每组测试数据,如果满足数独要求,输出YES,否则输出NO

二、修改思路:

我个人认为每次测试此代码都需要输入1个9*9的数字阵实在是麻烦,所以我在题目原有的代码上增加了我个人的代码使之可以快速高效的测试。

所以我增加以下三个函数来实现测试

void fprintf1 负责打印9*9的数字阵;
int myRand 是通过九宫格accord的第一行为[6, 4, 5, 7, 3, 9, 8, 1, 2], 则可获得的九宫格squa的第一行第一列元素这样产生:看accord对应元素为6,则看root中6后一位的数为7,则所求数字为7
int reRank 获得一个填满的九宫格accord
三 源代码
#include<iostream>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstring>
using namespace std;

int row(int arr[][10])
{
    int count[10], totalsub;//用count记录每个数字出现的次数,如果符合条件每个数字只出现一次
    for (int i = 1; i <= 9; i++)
    {
        memset(count, 0, 10 * sizeof(int));
        for (int j = 1; j <= 9; j++)
        {
            count[arr[i][j]]++;
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];//累乘只能等于1
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1;
}

int col(int arr[][10])//与行同理
{
    int count[10], totalsub;
    for (int i = 1; i <= 9; i++)
    {
        memset(count, 0, sizeof(int) * 10);
        for (int j = 1; j <= 9; j++)
        {
            count[arr[j][i]]++;
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1;
}
int section(int arr[][10])
{
    int count[10], totalsub;
    for (int i = 1; i <= 9; i++)//一共有9个区域,必须全部符合
    {
        int relrow, relcol;
        relrow = ((i - 1) / 3) * 3 + 1;//找出9个区域对应的行列
        relcol = ((i - 1) % 3) * 3 + 1;
        memset(count, 0, sizeof(int) * 10);
        for (int j = relrow; j < relrow + 3; j++)//判断原理同上
        {
            for (int k = relcol; k < relcol + 3; k++)
            {
                count[arr[j][k]]++;
            }
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1; }


int main() {
    int t;
    cin >> t;
    while (t--)
    {
        int arr[10][10];
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 9; j++)
            {
                cin >> arr[i][j];
            }
        }
        if (row(arr) && col(arr) && section(arr))//分为行列区域三个模块进行判断
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
    }
    return 0; }
 
 
四 修改过后的源代码:
 
#include<iostream>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstring>
using namespace std;

int long index1 = 0; 
int myRand(int range) 
{
    srand((unsigned)time( NULL ) + index1);
    index1++;
    return rand()%range + 1;     
}
int reRank(int root[9], int numb)
{    
    int i; 
    for(i = 0; i < 9; i++)
    {
        if(root[i] == numb)
            return i;
    }
    
    return 0;
}
void fprintf1(int squa[9][9])
{ 
    int i,j;
    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 9; j++)
        {   
            printf("%d ", squa[i][j]);
            if ((j == 2) || (j == 5)) //换列时加空格
                printf(" ");
        }
        printf("\n");
        if ((i == 2) || (i == 5))     //换行时加换行符
        {
            printf("\n");
        }
    }            
}

int row(int arr[][10])
{
    int count[10], totalsub;//用count记录每个数字出现的次数,如果符合条件每个数字只出现一次
    for (int i = 1; i <= 9; i++)
    {
        memset(count, 0, 10 * sizeof(int));
        for (int j = 1; j <= 9; j++)
        {
            count[arr[i][j]]++;
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];//累乘只能等于1
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1;
}

int col(int arr[][10])//与行同理
{
    int count[10], totalsub;
    for (int i = 1; i <= 9; i++)
    {
        memset(count, 0, sizeof(int) * 10);
        for (int j = 1; j <= 9; j++)
        {
            count[arr[j][i]]++;
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1; }

int section(int arr[][10]) {

    int count[10], totalsub;
    for (int i = 1; i <= 9; i++)//一共有9个区域,必须全部符合
    {
        int relrow, relcol;
        relrow = ((i - 1) / 3) * 3 + 1;//找出9个区域对应的行列
        relcol = ((i - 1) % 3) * 3 + 1;
        memset(count, 0, sizeof(int) * 10);
        for (int j = relrow; j < relrow + 3; j++)//判断原理同上
        {
            for (int k = relcol; k < relcol + 3; k++)
            {
                count[arr[j][k]]++;
            }
        }
        totalsub = 1;
        for (int k = 1; k <= 9; k++)
        {
            totalsub *= count[k];
        }
        if (totalsub != 1)
        {
            return 0;
        }
    }
    return 1; }


int main() {
         
int myRand(int range);
    int squa[9][9], accord[9][9]={   //定义用于生成数独的参照数组
{6, 4, 5, 7, 3, 9, 8, 1, 2}, {
2, 1, 8, 6, 4, 5, 9, 7, 3}, {
7, 3, 9, 2, 8, 1, 6, 4, 5}, {
5, 9, 6, 3, 7, 4, 2, 8, 1}, {
4, 8, 7, 5, 1, 2, 3, 6, 9}, {
3, 2, 1, 8, 9, 6, 7, 5, 4}, {
9, 5, 3, 4, 6, 7, 1, 2, 8}, {
8, 7, 2, 1, 5, 3, 4, 9, 6}, {
1, 6, 4, 9, 2, 8, 5, 3, 7}
    };
    int root[9];
    int answ[9][9]; //定义用于生成数组的一维数组和临时数组
    int i, j;
    int row1;
         
for(i = 0; i < 9; i++)
    {
        root[i] = myRand(9);
    }
    for(i = 0; i < 9; i++)
    {
        for(j = 0; j < i; j++)
        {
            if(root[i]==root[j]) //使root中元素各不相同
                root[i] = myRand(9);
        }
    }
    //随机产生完整九宫格
    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
        {
            row1 = reRank(root,accord[i][j]);
            squa[i][j] = root[(row1+1)%9];
        }
    }
    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 9; j++)
        {
            answ[i][j] = squa[i][j];
        }
    }
    fprintf1(squa);
                                 
int arr[10][10];
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 9; j++)
            {
                arr[i][j]= squa[i-1][j-1];
            }
        }
        if (row(arr) && col(arr) && section(arr))//分为行列区域三个模块进行判断
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
         
return 0; }

 

 每执行一遍都会产生新结果

 

 

 五 心得体会

   虽然看似我增加了简单的三个函数但在编写的过程中学会了许多新知识,如:srand函数是随机数发生器的初始化函数,提供给它一个种子通过使用系统时间来初始化(使用 time函数来获得系统时间然后将time_t型数据转化为(unsigned)型再传给srand函数,即: srand((unsigned) time(&t));),可以防止产生每次都不一样的随机数。

posted @   kyrie1234  阅读(109)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示