C语言程序设计基础|数独

题目一:数独验证

题目描述:

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

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

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

C语言程序设计基础|数独_第1张图片

输入要求:

测试次数

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

输出要求:

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

#include
#include
#include
#include
#include
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;
}

问题二:数组求解

题目描述:

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

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

在上题数独验证的代码上,增加函数,根据输入的9*9盘面已知数字,求解数独,并输出解。

输入要求:

输入1个9*9的数字阵,数字范围0-9,0表示该位置无数字,需填数。

输出要求:

输出数独解(9*9的矩阵值)

#include
#include
#include
#include
#include
using namespace std;

int flag;
int simplerepeat(int arr[][10], int x, int y, int site)
{
    for (int i = 1; i <= 9; i++)//每一列不重复
    {
        if (arr[x][i] == site)//如果重复就返回0到上一级
        {
            return 0;
        }
    }
    for (int j = 1; j <= 9; j++)//每一行不重复
    {
        if (arr[j][y] == site)//如果重复就返回0到上一级
        {
            return 0;
        }
    };
    return 1;
}

int sectionrepeat(int arr[][10], int x, int y, int site)
{
    int partx, party;
    partx = ((x - 1) / 3) * 3 + 1;
    party = ((y - 1) / 3) * 3 + 1;
    for (int i = partx; i < partx + 3; i++)//每个区域里也不重复,如果重复就返回上一级
    {
        for (int j = party; j < party + 3; j++)
        {
            if (arr[i][j] == site)
            {
                return 0;
            }
        }
    }
    return 1;
}

void DFS(int arr[][10], int x, int y)
{
    if (y > 9)//如果列数大于9就换行
    {
        x++;
        y = 1;
    }
    if (x > 9)//如果行数大于9就输出最终解
    {
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 9; j++)
            {
                cout << arr[i][j];
                if (j != 9)
                {
                    cout << " ";
                }
                else
                {
                    cout << endl;
                }
            }
        }
        return;
    }
    if (arr[x][y] == 0)
    {
        for (int i = 1; i <= 9; i++)
        {
            if (simplerepeat(arr, x, y, i) && sectionrepeat(arr, x, y, i))
            {
                arr[x][y] = i;//符合条件就赋值
                DFS(arr, x, y + 1);//然后遍历下一个位置
            }
        }
        arr[x][y] = 0;//遍历完返回上一级
    }
    else//有数就直接下一个位置
    {
        DFS(arr, x, y + 1);
    }
}

int main()
{
    int arr[10][10];
    for (int i = 1; i <= 9; i++)//输入需要求解的数独
    {
        for (int j = 1; j <= 9; j++)
        {
            cin >> arr[i][j];
        }
    }
    DFS(arr, 1, 1);
    return 0;
}

你可能感兴趣的:(Simple,C,c语言,c++,算法)