Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7613 | Accepted: 2696 |
Description
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. | 2 | 7 | 3 | 8 | . | . | 1 | . |
. | 1 | . | . | . | 6 | 7 | 3 | 5 |
. | . | . | . | . | . | . | 2 | 9 |
3 | . | 5 | 6 | 9 | 2 | . | 8 | . |
. | . | . | . | . | . | . | . | . |
. | 6 | . | 1 | 7 | 4 | 5 | . | 3 |
6 | 4 | . | . | . | . | . | . | . |
9 | 5 | 1 | 8 | . | . | . | 7 | . |
. | 8 | . | . | 6 | 5 | 3 | 4 | . |
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534. ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3. end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341 416837529982465371735129468571298643293746185864351297647913852359682714128574936
Source
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int tmp[9][9] = {{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8}};
int Int(){
char ch;int tmp = 0;
while (ch = getchar()) if (ch >= '0' && ch <='9') break;
for (; ch >= '0' && ch <= '9'; ch = getchar()) tmp = tmp * 10 + ch - '0';
return tmp;
}
int tmp1[9], tmp2[9], tmp3[9];
int a[9][9];
int ans[9][9];
bool ok;
int num[1 << 12];
void init(){
memset(tmp1, 0, sizeof(tmp1));
memset(tmp2, 0, sizeof(tmp2));
memset(tmp3, 0, sizeof(tmp3));
memset(ans, 0, sizeof(ans));
memset(a, 0, sizeof(a));
ok = false;
for (int i = 0; i < 9; i ++)
for (int j = 0; j < 9; j ++){
char ch = 0;
while (ch = getchar()){
if ((ch >= '0' && ch <= '9') || ch == '.') break;
if (ch == 'e') exit(0);
}
if (ch != '.') a[i][j] = ch - '0';
if (a[i][j]){
ans[i][j] = a[i][j];
tmp1[i] ^= (1 << a[i][j] - 1);
tmp2[j] ^= (1 << a[i][j] - 1);
tmp3[tmp[i][j]] ^= (1 << a[i][j] - 1);
}
}
}
int find_next(int &x, int &y){
x = 9, y = 0;
int mini = 99999;
for (int i = 0; i < 9; i ++)
for (int j = 0; j < 9; j ++)
if (ans[i][j] == 0 && num[(511 ^ tmp1[i]) & (511 ^ tmp2[j]) & (511 ^ tmp3[tmp[i][j]])] < mini){
x = i, y = j;
mini = num[(511 ^ tmp1[i]) & (511 ^ tmp2[j]) & (511 ^ tmp3[tmp[i][j]])];
}
}
void dfs(int x, int y){
if (ok)return;
if (a[x][y]){
int xx = 0, yy = 0;
find_next(xx, yy);
dfs(xx, yy);
return;
}
if (x == 9 && y == 0){
for (int i = 0; i < 9; i ++){
for (int j = 0; j < 9; j ++)
cout <<ans[i][j] ;
}
cout <<endl;
ok = true;
return;
}
for (int i = 1; i <= 9; i ++)
if (!(tmp1[x] & (1 << i - 1)) && !(tmp2[y] & (1 << i - 1)) && !(tmp3[tmp[x][y]] & (1 << i - 1))){
ans[x][y] = i;
tmp1[x] ^= (1 << i - 1);
tmp2[y] ^= (1 << i - 1);
tmp3[tmp[x][y]] ^= (1 << i - 1);
int xx = 0, yy = 0;
find_next(xx, yy);
dfs(xx, yy);
ans[x][y] = 0;
tmp1[x] ^= (1 << i - 1);
tmp2[y] ^= (1 << i - 1);
tmp3[tmp[x][y]] ^= (1 << i - 1);
}
}
int main(){
for (int i = 0; i <= 512; i ++)
for (int j = 0; j < 9; j ++)
if (i & (1 << j)) num[i] ++;
while (1){
init();
dfs(0, 0);
}
return 0;
}