洛谷P1784.数独
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;
}