洛谷P1784.數獨

栗悟饭与龟功気波發表於2024-11-13

P1784數獨

思路

這個題目最麻煩的是如何判斷

我們需要判斷每一行每一列每一個九宮格

這裡有個小技巧,把每一行,每一列,每一個九宮格哪個數有沒有被用過用陣列存起來 哪個數字屬於哪個九宮格也可以先先存起來

int id[10][10] = {{0,0,0,0,0,0,0,0,0,0},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9}};
// id[i][j] (i, j)這個位置的元素屬於哪個格子
bool row[10][10]; // row[i][j] 第i行j這個數有沒有被用過
bool line[10][10]; // line[i][j] 第i列j這個數有沒有被用過
bool sub[10][10]; // sub[i][j] 第i個格子j這個數有沒有被用過

然後我們將每一個空格的位置記錄下來,\(dfs\)每一個空格的位置就好了

程式碼

#include <bits/stdc++.h>
#define endl '\n'
//#define int long long
const int maxn = 2e5 + 5;
const int inf = 1e18;

struct custom_hash 
{
	static uint64_t splitmix64(uint64_t x) 
    {
		x ^= x << 13;
		x ^= x >> 7;
		x ^= x << 17;
		return x; 
	}
	size_t operator () (uint64_t x) const 
    {
		static const uint64_t FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count(); // 時間戳
		return splitmix64(x + FIXED_RANDOM);
	}
};

struct Empty
{
    int x, y;
}arr[100];

int id[10][10] = {{0,0,0,0,0,0,0,0,0,0},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,1,1,1,2,2,2,3,3,3},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,4,4,4,5,5,5,6,6,6},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9},
                  {0,7,7,7,8,8,8,9,9,9}};
// id[i][j] (i, j)這個位置的元素屬於哪個格子
int cnt = 0;
int mat[10][10];
bool row[10][10]; // row[i][j] 第i行j這個數有沒有被用過
bool line[10][10]; // line[i][j] 第i列j這個數有沒有被用過
bool sub[10][10]; // sub[i][j] 第i個格子j這個數有沒有被用過
bool ifexit = false;
// 列印矩陣
void print()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            std::cout << mat[i][j] << " ";
        }
        std::cout << endl;
    }
}

void dfs(int c)
{
    if (ifexit) return;
    if (c > cnt)
    {
        print();
        ifexit = true;
        return;
    }
    int xx = arr[c].x, yy = arr[c].y;
    for (int i = 1; i <= 9; i++)
    {
        if (row[xx][i] == 0 && line[yy][i] == 0 && sub[id[xx][yy]][i] == 0)
        {
            mat[xx][yy] = i;
            row[xx][i] = 1;
            line[yy][i] = 1;
            sub[id[xx][yy]][i] = 1;
            dfs(c + 1);
            mat[xx][yy] = 0;
            row[xx][i] = 0;
            line[yy][i] = 0;
            sub[id[xx][yy]][i] = 0;
        }
    }
}

void solve()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            std::cin >> mat[i][j];
            if (mat[i][j] == 0)
            {
                arr[++cnt].x = i;
                arr[cnt].y = j;
            }
            else
            {
                row[i][mat[i][j]] = 1;
                line[j][mat[i][j]] = 1;
                sub[id[i][j]][mat[i][j]] = 1;
            }
        }
    }
    dfs(1);
}

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); std::cout.tie(nullptr);
    //freopen("out.txt", "w", stdout);
    int t = 1;
    //std::cin >> t;
    while(t--)
    {
        solve();
    }
    return 0;
}