Sudoku is a popular single player game. The objective is to fill a 9x9 matrix with digits so that each column, each row, and all 9 non-overlapping 3x3 sub-matrices contain all of the digits from 1 through 9. Each 9x9 matrix is partially completed at the start of game play and typically has a unique solution.
Given a completed N2xN2 Sudoku matrix, your task is to determine whether it is a validsolution. A valid solution must satisfy the following criteria:
- Each row contains each number from 1 to N2, once each.
- Each column contains each number from 1 to N2, once each.
- Divide the N2xN2 matrix into N2 non-overlapping NxN sub-matrices. Each sub-matrix contains each number from 1 to N2, once each.
You don't need to worry about the uniqueness of the problem. Just check if the given matrix is a valid solution.
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with an integer N. The next N2 lines describe a completed Sudoku solution, with each line contains exactly N2 integers. All input integers are positive and less than 1000.
Output
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is "Yes" (quotes for clarity only) if it is a valid solution, or "No" (quotes for clarity only) if it is invalid. Note that the judge is case-sensitive, so answers of "yes" and "no" will not be accepted.
Limits
1 ≤ T ≤ 100.
Small dataset
N = 3.
Large dataset
3 ≤ N ≤ 6.
Sample
Use Set to check whether each element is just appearing once either in a line, a row, or a subMatrix. Time Complexity O(N^2 * N^2).
My solution: (Your opinion is highly appreciated)
package codeJam.google.com;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Scanner;
/**
* @author Zhenyi 2013 Dec 24, 2013 1:35:59 PM
*/
public class SudokuChecker {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new File(
"C:/Users/Zhenyi/Downloads/A-small-practice.in"));
FileWriter out = new FileWriter(
"C:/Users/Zhenyi/Downloads/A-small-practice.out");
// Scanner in = new Scanner(new
// File("C:/Users/Zhenyi/Downloads/A-large-practice.in"));
// FileWriter out = new
// FileWriter("C:/Users/Zhenyi/Downloads/A-large-practice.out");
int T = in.nextInt();
for (int cases = 1; cases <= T; cases++) {
int N = in.nextInt();
int[][] sArray = new int[N * N][N * N];
for (int i = 0; i < N * N; i++) {
for (int j = 0; j < N * N; j++) {
sArray[i][j] = in.nextInt();
}
}
HashSet<Integer> hs = new HashSet<Integer>();
for (int i = 1; i <= N * N; i++) {
hs.add(i);
}
boolean check = true;
// horizontal
for (int i = 0; i < N * N && check; i++) {
@SuppressWarnings("unchecked")
HashSet<Integer> tmp = (HashSet<Integer>) hs.clone();
for (int j = 0; j < N * N; j++) {
tmp.remove(sArray[i][j]);
}
if (tmp.size() != 0) {
check = false;
}
}
// vertical
for (int j = 0; j < N * N && check; j++) {
@SuppressWarnings("unchecked")
HashSet<Integer> tmp = (HashSet<Integer>) hs.clone();
for (int i = 0; i < N * N; i++) {
tmp.remove(sArray[i][j]);
}
if (tmp.size() != 0) {
check = false;
}
}
// subMatrix
for (int iShift = 0; iShift < N * N && check; iShift += N) {
for (int jShift = 0; jShift < N * N && check; jShift += N) {
@SuppressWarnings("unchecked")
HashSet<Integer> tmp = (HashSet<Integer>) hs.clone();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
tmp.remove(sArray[i + iShift][j + jShift]);
}
}
if (tmp.size() != 0) {
check = false;
}
}
}
if (check) {
out.write("Case #" + cases + ": Yes\n");
} else {
out.write("Case #" + cases + ": No\n");
}
}
in.close();
out.flush();
out.close();
}
}