数独游戏代码C++解法

题目要求很简单 就是给一个6*6的数独输入 关于6 * 6的数独介绍:

玩数独你应该知道,每行/列数字不能重复,每个3*2的方格内不能重复,该题目是来自某公司的笔试题。采用C++算法进行求解。该代码也没有考虑无解的情况,和力扣上的一道类似。

1 2 3 4 5 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

求解出该输出

1 2 3 | 4 5 6
4 5 6 | 1 2 3
------|------
3 1 4 | 2 6 5
2 6 5 | 3 1 4
-------------
5 3 1 | 6 4 2
6 4 2 | 5 3 1

直接上代码通过暴力回溯直接 找到最佳值

#include <bits/stdc++.h>

using namespace std;

int m = 6; // 阶数
int boxRow = 2, boxCol = 3;
bool sudokuSolved = false;

vector<vector<int> > rowOccupied(6, vector<int>(7));
vector<vector<int> > colOccupied(6, vector<int>(7));
vector<vector<int> > boxOccupied(6, vector<int>(7));
vector<vector<int> > shudoPan(m, vector<int>(m));

void Initialize(vector<vector<int> > Occupied) {
    for(int i = 0; i < m; i++) {
        for(int k = 0; k < m+1; k++) {
            Occupied[i][k] = 0;
        }
    }
}


bool couldPlace(int d, int row, int col) {

    //判断某格子是否可以放置
    if(boxRow > 0) {
        int idx = (row / boxRow ) * boxRow + col / boxCol;
        return rowOccupied[row][d] + colOccupied[col][d] + boxOccupied[idx][d] == 0;
    }else {
        return rowOccupied[row][d] + colOccupied[col][d] == 0;
    }

}

void backtrack(int row, int col) {


    if(shudoPan[row][col] == 0) {
        for(int d = 1; d <= m; d++) {
            int idx = 0;
            if(boxRow > 0) {
                idx = (row / boxRow ) * boxRow + col / boxCol;
            }

            if(couldPlace(d, row, col)) {
                //填充数字,并设置填充限制
                boxOccupied[idx][d]++;
                rowOccupied[row][d]++;
                colOccupied[col][d]++;
                shudoPan[row][col] = d;
                //是否填充到最后一格
                if ((col == m-1) && (row == m-1)) {
                    sudokuSolved = true;
                }
                else {
                    //当到达最后一列的格子,下一个格子跳转到下一行
                    if (col == m-1) {
                        backtrack(row + 1, 0);
                    }else {
                        backtrack(row, col + 1);
                    }
                }
                if(!sudokuSolved) {//移除填充后无法进行后续填充的数

                    boxOccupied[idx][d]--;
                    rowOccupied[row][d]--;
                    colOccupied[col][d]--;
                    shudoPan[row][col] = 0;
                }
            }
        }
    }else {
        if ((col == m-1) && (row == m-1)) {
            sudokuSolved = true;
        }
        else {
            //当到达最后一列的格子,下一个格子跳转到下一行
            if (col == m-1) {
                backtrack(row + 1, 0);
            }else {
                backtrack(row, col + 1);
            }
        }
    }
}

void solveSudoku() {

    // 初始化某数所在行、列、宫
    for (int i = 0; i < m; i++) {
        for (int k = 0; k < m; k++) {
            int num = shudoPan[i][k];
            if (num != 0) {
                int d = num;
                if(boxRow > 0) {
                    int idx = (i / boxRow ) * boxRow + k / boxCol;
                    boxOccupied[idx][d]++;
                }
                rowOccupied[i][d]++;
                colOccupied[k][d]++;
            }
        }
    }
    backtrack(0, 0);
}


int main() {

    for(int i = 0; i < m; i++)
        for(int j = 0; j < m; j++)
            cin >> shudoPan[i][j];
    solveSudoku();
    for(int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
            cout << shudoPan[i][j] << " ";
            if(j == 2)
                cout << "| ";
        }
        cout << endl;
        if (i == 1 || i == 3)
            cout << "------|------" << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/z_modi/article/details/126373833
今日推荐