703. 数独检查
数独是一种流行的单人游戏。
目标是用数字填充9x9
矩阵,使每列,每行和所有9
个非重叠的3x3
子矩阵包含从1
到9
的所有数字。
每个9x9
矩阵在游戏开始时都会有部分数字已经给出,通常有一个独特的解决方案。
给定完成的 N 2 ∗ N 2 N^2∗N^2 N2∗N2数独矩阵,你的任务是确定它是否是有效的解决方案。
有效的解决方案必须满足以下条件:
每行包含从
1
1
1到
N
2
N^2
N2的每个数字,每个数字一次。
每列包含从
1
1
1到
N
2
N^2
N2的每个数字,每个数字一次。
将
N
2
∗
N
2
N^2∗N^2
N2∗N2矩阵划分为
N
2
N^2
N2个非重叠
N
∗
N
N∗N
N∗N子矩阵。 每个子矩阵包含从
1
1
1到
N
2
N^2
N2的每个数字,每个数字一次。
你无需担心问题的唯一性,只需检查给定矩阵是否是有效的解决方案即可。
输入格式
第一行包含整数
T
T
T,表示共有
T
T
T组测试数据。
每组数据第一行包含整数 N N N。
接下来 N 2 N^2 N2行,每行包含 N 2 N^2 N2个数字(均不超过 1000 1000 1000),用来描述完整的数独矩阵。
输出格式
每组数据输出一个结果,每个结果占一行。
结果表示为“Case #x: y”
,其中x
是组别编号(从
1
1
1开始),如果给定矩阵是有效方案则y
是Yes
,否则y
是No
。
数据范围
1
≤
T
≤
100
,
1≤T≤100,
1≤T≤100,
3
≤
N
≤
6
3≤N≤6
3≤N≤6
输入样例:
3
3
5 3 4 6 7 8 9 1 2
6 7 2 1 9 5 3 4 8
1 9 8 3 4 2 5 6 7
8 5 9 7 6 1 4 2 3
4 2 6 8 5 3 7 9 1
7 1 3 9 2 4 8 5 6
9 6 1 5 3 7 2 8 4
2 8 7 4 1 9 6 3 5
3 4 5 2 8 6 1 7 9
3
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
3
5 3 4 6 7 8 9 1 2
6 7 2 1 9 5 3 4 8
1 9 8 3 4 2 5 6 7
8 5 9 7 6 1 4 2 3
4 2 6 8 999 3 7 9 1
7 1 3 9 2 4 8 5 6
9 6 1 5 3 7 2 8 4
2 8 7 4 1 9 6 3 5
3 4 5 2 8 6 1 7 9
输出样例:
Case #1: Yes
Case #2: No
Case #3: No
思路:
使用hashSet
存数据,分别检验行,列,小方块范围的数是否满足数据要求
检查的方式是:每个行,列,小方块内的数字全部存入hashSet
,如果hashSet
的大小 < n*n
则不满足
注意越界检查
Java代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
public class Main {
static int[][] a = new int[40][40];
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(reader.readLine());
int s = 1;
while (s <= t){
int n = Integer.parseInt(reader.readLine());
int m = n*n;
for (int i = 1; i <= m; i++) {
String[] str = reader.readLine().split(" ");
for (int j = 1; j <= m; j++) {
a[i][j] = Integer.parseInt(str[j - 1]);
}
}
if(check_row(a, n) && check_col(a, n) && check_square(a, n)){
System.out.println("Case #" + s + ": Yes");
}else {System.out.println("Case #" + s + ": No");}
s ++;
}
}
private static boolean check_square(int[][] a, int n) {
int m = n*n;
for (int i = 1; i <= m; i += n) {
for (int j = 1; j <= m; j+= n) {
HashSet<Integer> hashSet = new HashSet<Integer>();
for (int k = i; k <= i + n; k++) {
for (int l = j; l <= j + n; l++) {
hashSet.add(a[k][l]);
}
}
if (hashSet.size() < m) return false;
}
}
return true;
}
private static boolean check_col(int[][] a, int n) {
int m = n*n;
for (int i = 1; i <= m; i++) {
HashSet<Integer> hashSet = new HashSet<Integer>();
for (int j = 1; j <= m; j++) {
if(a[i][j] < 1 || a[i][j] > m) return false;
hashSet.add(a[i][j]);
}
if (hashSet.size() < m) return false;
}
return true;
}
private static boolean check_row(int[][] a, int n) {
int m = n*n;
for (int i = 1; i <= m; i++) {
HashSet<Integer> hashSet = new HashSet<Integer>();
for (int j = 1; j <= m; j++) {
if(a[i][j] < 1 || a[i][j] > m) return false;
hashSet.add(a[j][i]);
}
if (hashSet.size() < m) return false;
}
return true;
}
}