时间限制 | 内存限制 |
---|---|
1000 ms |
65536 KB |
# 题目描述
Moca 最近发现了一种叫做数独的益智游戏。
经典的数独规则是这样的:
-
将一个 的方格分为 个 的小方格,每个 方格称为一个宫
-
开始时一些方格中的数字是给定的,玩家需要根据推理,填写剩余方格中的数字,直到所有方格中都被填上了数字
-
最后 在每一行、每一列、每一宫中,数字 1 - 9 都出现且只出现一次,则填写正确
Moca 喜欢做数独,但她不喜欢检查自己做的数独是否正确,尽管这很简单。所以,她希望你能帮她写一个程序,对于一个给定的初始状态,检查她做的数独是否正确。
# 输入
第一行一个正整数 ,表示 Moca 做了多少数独,。
接下来 组输入,每组输入之前有一个空行。每组输入 行:前九行每行九个数字,为初始的数独局面, 代表待填写的数字,其余数字代表初始给定的数字,保证初始局面中所有数字一定是 到 中的一个;接下来一行空行;后九行每行九个数字,表示对应做出来的数独,保证做出来的数独中的数字一定是 到 中的一个。
# 输出
输出 行,如果第 组做出来的数独对于第 组初始局面数独填写正确,那么对应输出行输出 Moca finish this sudoku perfectly!
;否则(包括做出来的数独虽然正确,但是不符合给定的初始局面的情况)输出 Moca is so careless!
。
# 输入样例
3 | |
0 2 0 4 0 0 0 0 0 | |
4 5 0 7 0 0 0 0 3 | |
0 8 9 0 3 0 0 0 6 | |
2 0 0 0 0 0 8 0 0 | |
0 9 0 0 0 0 0 6 5 | |
3 0 5 8 7 0 2 0 0 | |
5 0 0 0 0 0 9 7 8 | |
6 0 0 9 0 0 0 0 1 | |
0 7 0 5 1 0 0 4 0 | |
1 2 3 4 5 6 7 8 9 | |
4 5 6 7 9 8 1 2 3 | |
7 8 9 1 3 2 4 5 6 | |
2 1 4 3 6 5 8 9 7 | |
8 9 7 2 4 1 3 6 5 | |
3 6 5 8 7 9 2 1 4 | |
5 3 1 6 2 4 9 7 8 | |
6 4 2 9 8 7 5 3 1 | |
9 7 8 5 1 3 6 4 2 | |
0 2 0 4 0 0 0 0 0 | |
4 5 0 7 0 0 0 0 3 | |
0 8 9 0 3 0 0 0 6 | |
2 0 0 0 0 0 8 0 0 | |
0 9 0 0 0 0 0 6 5 | |
3 0 5 8 7 0 2 0 0 | |
5 0 0 0 0 0 9 7 8 | |
6 0 0 9 0 0 0 0 1 | |
0 7 0 5 1 0 0 4 0 | |
1 2 3 4 5 6 7 8 9 | |
4 5 6 7 9 8 1 2 3 | |
7 8 9 1 3 2 4 5 6 | |
2 1 4 3 6 5 8 9 7 | |
8 9 7 2 4 1 3 6 5 | |
3 6 5 8 7 9 2 1 4 | |
5 3 1 6 2 4 9 7 8 | |
6 4 2 9 8 7 5 3 1 | |
9 7 8 5 1 3 6 4 1 | |
0 2 0 4 0 0 0 0 0 | |
4 5 0 7 0 0 0 0 3 | |
0 8 9 0 3 0 0 0 6 | |
2 0 0 0 0 0 8 0 0 | |
0 9 0 0 0 0 0 6 5 | |
3 0 5 8 7 0 2 0 0 | |
5 0 0 0 0 0 9 7 8 | |
6 0 0 9 0 0 0 0 1 | |
0 7 0 5 1 0 0 4 0 | |
1 2 3 6 5 4 7 8 9 | |
4 5 6 9 8 7 1 2 3 | |
7 8 9 3 2 1 4 5 6 | |
8 9 7 4 1 2 3 6 5 | |
3 6 5 7 9 8 2 1 4 | |
2 1 4 5 6 3 8 9 7 | |
5 3 1 2 4 6 9 7 8 | |
6 4 2 8 7 9 5 3 1 | |
9 7 8 1 3 5 6 4 2 |
# 输出样例
Moca finish this sudoku perfectly! | |
Moca is so careless! | |
Moca is so careless! |
# 样例解释
对于第 组输入,补全后的数独正确,且符合初始局面;对于第 组输入,补全后的数独不正确,在九行和九列中都出现了两次 ;对于第 组输入,虽然补全后的数独正确,但并不符合初始局面(如第一行第四列初始局面给定的数字是 ,但是 Moca 补全的数独中对应位置的数字却是 ),所以也是错的。
# 题解:模拟
我们开两个二维数组存下初始和结束局面,随后按题意模拟即可。
参考代码:
#include <stdio.h> | |
#include <stdbool.h> | |
#include <string.h> | |
int ini[10][10], ans[10][10], cnt[10]; | |
bool CheckNumber() | |
{ | |
bool flag = true; | |
for (int i = 1; i <= 9; ++ i) | |
if (cnt[i] != 1) | |
flag = false; | |
return flag; | |
} | |
bool Check() | |
{ | |
bool flag = true; | |
for (int i = 1; i <= 9; ++ i) | |
for (int j = 1; j <= 9; ++ j) | |
if (ini[i][j] && ini[i][j] != ans[i][j]) | |
flag = false; | |
for (int i = 1; i <= 9; ++ i) | |
{ | |
memset(cnt, 0, sizeof(cnt)); | |
for (int j = 1; j <= 9; ++ j) | |
++ cnt[ans[i][j]]; | |
if (!CheckNumber()) | |
flag = false; | |
memset(cnt, 0, sizeof(cnt)); | |
for (int j = 1; j <= 9; ++ j) | |
++ cnt[ans[j][i]]; | |
if (!CheckNumber()) | |
flag = false; | |
} | |
for (int i = 1; i <= 9; i += 3) | |
for (int j = 1; j <= 9; j += 3) | |
{ | |
memset(cnt, 0, sizeof(cnt)); | |
for (int u = i; u <= i + 2; ++ u) | |
for (int v = j; v <= j + 2; ++ v) | |
++ cnt[ans[u][v]]; | |
if (!CheckNumber()) | |
flag = false; | |
} | |
return flag; | |
} | |
int main() | |
{ | |
// freopen("E.in", "r", stdin); | |
// freopen("E.out", "w", stdout); | |
int T; | |
scanf("%d", &T); | |
while (T -- ) | |
{ | |
for (int i = 1; i <= 9; ++ i) | |
for (int j = 1; j <= 9; ++ j) | |
scanf("%d", &ini[i][j]); | |
for (int i = 1; i <= 9; ++ i) | |
for (int j = 1; j <= 9; ++ j) | |
scanf("%d", &ans[i][j]); | |
if (Check()) | |
puts("Moca finish this sudoku perfectly!"); | |
else | |
puts("Moca is so careless!"); | |
} | |
return 0; | |
} |