数独游戏 / 数独
题目链接:luogu P1784 / ybt高效进阶1-4-2
题目大意
就是给你一个数独,要你填完它。
思路
这道题其实就是爆搜。
你就直接一个位置一个位置的看,然后每个位置
1
∼
9
1\sim 9
1∼9 看放哪个数。
要能放这个数,要有几个条件:
- 这个数没有一开始就填好
- 它不跟它这一行的某个数相同,弄一个变量记录某一行有那些数就可以了
- 它不跟它这一列的某个数相同,弄一个变量记录某一列有那些数就可以了
- 它不跟它这个区块的某个数相同,也弄一个变量记录。
下面的图片中,同一个颜色的就是一个区块:
也就是说这个:
这是一个格子对应的不能跟它一样的格子。
(粉色代表同一行,黄色代表同一列,蓝色就是同一区块)
那我们就按照上面的条件爆搜,就可以得出答案。
时间是可以的,不会超时,一找到就整个退出就可以不超时了。
代码
luogu P1784
#include<cstdio>
#include<cstring>
using namespace std;
bool block[11][11], heng[11][11], zong[11][11], yes;
int a[11][11];
void write() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++)
printf("%d ", a[i][j]);
printf("\n");
}
return ;
}
int get_block(int x, int y) {
if (x <= 3) return 1 + (y - 1) / 3;
else if (x <= 6) return 4 + (y - 1) / 3;
else return 7 + (y - 1) / 3;
}
void dfs(int x, int y) {
if (y > 9) {
y = 1;
x++;
}
if (x == 10 && y == 1) {
write();
yes = 1;
return ;
}
if (a[x][y] != -1) {
dfs(x, y + 1);
return ;
}
for (int i = 1; i <= 9; i++) {
if (!block[get_block(x, y)][i] && !heng[x][i] && !zong[y][i]) {
block[get_block(x, y)][i] = 1;
heng[x][i] = 1;
zong[y][i] = 1;
a[x][y] = i;
dfs(x, y + 1);
if (yes) return ;
block[get_block(x, y)][i] = 0;
heng[x][i] = 0;
zong[y][i] = 0;
a[x][y] = -1;
}
}
return ;
}
int main() {
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++) {
scanf("%d", &a[i][j]);
if (a[i][j]) {
block[get_block(i, j)][a[i][j]] = 1;
heng[i][a[i][j]] = 1;
zong[j][a[i][j]] = 1;
}
else a[i][j] = -1;
}
dfs(1, 1);
return 0;
}
ybt高效进阶1-4-2
#include<cstdio>
#include<cstring>
using namespace std;
bool block[11][11], heng[11][11], zong[11][11], yes;
int a[11][11];
char c[91];
void write() {
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
printf("%d", a[i][j]);
printf("\n");
return ;
}
int get_block(int x, int y) {
if (x <= 3) return 1 + (y - 1) / 3;
else if (x <= 6) return 4 + (y - 1) / 3;
else return 7 + (y - 1) / 3;
}
void dfs(int x, int y) {
if (y > 9) {
y = 1;
x++;
}
if (x == 10 && y == 1) {
write();
yes = 1;
return ;
}
if (a[x][y] != -1) {
dfs(x, y + 1);
return ;
}
for (int i = 1; i <= 9; i++) {
if (!block[get_block(x, y)][i] && !heng[x][i] && !zong[y][i]) {
block[get_block(x, y)][i] = 1;
heng[x][i] = 1;
zong[y][i] = 1;
a[x][y] = i;
dfs(x, y + 1);
if (yes) return ;
block[get_block(x, y)][i] = 0;
heng[x][i] = 0;
zong[y][i] = 0;
a[x][y] = -1;
}
}
return ;
}
int main() {
scanf("%s", &c);
while (c[0] != 'e' || c[1] != 'n' || c[2] != 'd') {
memset(block, 0, sizeof(block));
memset(heng, 0, sizeof(heng));
memset(zong, 0, sizeof(zong));
yes = 0;
for (int i = 0; i < 81; i++)
if (c[i] != '.') {
a[1 + (i) / 9][i % 9 + 1] = c[i] - '0';
block[get_block(1 + (i) / 9, i % 9 + 1)][c[i] - '0'] = 1;
heng[1 + (i) / 9][c[i] - '0'] = 1;
zong[i % 9 + 1][c[i] - '0'] = 1;
}
else a[1 + (i) / 9][i % 9 + 1] = -1;
dfs(1, 1);
scanf("%s", &c);
}
return 0;
}