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
用Dancing-Links玩数独
324个限制
1-81列,每个格子是否填数
82-162列,每行1-9的填写情况
163-243列,每列1-9的填写情况
244-324列,每宫1-9的填写情况
然后暴力跑Dancing-Links就好了
为什么感觉爆搜题很码农啊
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 6020;
const int MAXM = 350;
const int INF = 1e9 + 7;
int L[MAXN], R[MAXN], U[MAXN], D[MAXN], S[MAXM];
int pos[MAXN], Col[MAXN];
int mp[MAXN][MAXM];
int head[10][10][10], cnt;
char ch[100];
inline void init()
{
for( int i = 0 ; i <= 324 ; i++ )
S[ i ] = 0, L[ i ] = i - 1, R[ i ] = i + 1, U[ i ] = D[ i ] = i;
L[ R[ 324 ] = 0 ] = cnt = 324;
}
inline int getpos(int x, int y) { return ( x - 1 ) / 3 * 3 + ( y - 1 ) / 3; }
inline void insert(int c, int cnt)
{
U[ D[ U[ c ] ] = cnt ] = U[ c ];
D[ U[ c ] = cnt ] = c;
S[ c ]++;
Col[ cnt ] = c;
}
inline void ins(int x, int y, int k)
{
for( int i = cnt + 1 ; i <= cnt + 4 ; i++ )
L[ i ] = i - 1, R[ i ] = i + 1, pos[ i ] = 100 * x + 10 * y + k;
L[ R[ cnt + 4 ] = cnt + 1 ] = cnt + 4;
head[ x ][ y ][ k ] = cnt + 1;
insert( ( x - 1 ) * 9 + y, cnt + 1 );
insert( 81 + ( x - 1 ) * 9 + k, cnt + 2 );
insert( 162 + ( y - 1 ) * 9 + k, cnt + 3 );
insert( 243 + getpos( x, y ) * 9 + k, cnt + 4 );
cnt += 4;
}
inline void remove(int c)
{
L[ R[ c ] ] = L[ c ];
R[ L[ c ] ] = R[ c ];
for( int i = D[ c ] ; i ^ c ; i = D[ i ] )
for( int j = R[ i ] ; j ^ i ; j = R[ j ] )
{
U[ D[ j ] ] = U[ j ];
D[ U[ j ] ] = D[ j ];
S[ Col[ j ] ]--;
}
}
inline void resume(int c)
{
for( int i = U[ c ] ; i ^ c ; i = U[ i ] )
for( int j = L[ i ] ; j ^ i ; j = L[ j ] )
{
U[ D[ j ] ] = D[ U[ j ] ] = j;
S[ Col[ j ] ]++;
}
L[ R[ c ] ] = R[ L[ c ] ] = c;
}
inline bool dfs(int dep)
{
if( dep > 81 ) return true;
int c, mn = INF;
for( int i = R[ 0 ] ; i ; i = R[ i ] )
if( !S[ i ] ) return false;
else if( S[ i ] < mn ) mn = S[ i ], c = i;
remove( c );
for( int i = D[ c ] ; i ^ c ; i = D[ i ] )
{
int tmp = pos[ i ];
mp[ tmp / 100 ][ tmp / 10 % 10 ] = tmp % 10;
for( int j = R[ i ] ; j ^ i ; j = R[ j ] )
remove( Col[ j ] );
if( dfs( dep + 1 ) ) return true;
for( int j = L[ i ] ; j ^ i ; j = L[ j ] )
resume( Col[ j ] );
}
resume( c );
return false;
}
int main()
{
while( true )
{
scanf( "%s", ch + 1 );
if( ch[ 1 ] == 'e' ) return 0;
cnt = 0;
for( int i = 1 ; i <= 9 ; i++ )
for( int j = 1 ; j <= 9 ; j++ )
{
if( ch[ ++cnt ] == '.' ) mp[ i ][ j ] = 0;
else mp[ i ][ j ] = ch[ cnt ] - '0';
}
init();
for( int i = 1 ; i <= 9 ; i++ )
for( int j = 1 ; j <= 9 ; j++ )
{
if( mp[ i ][ j ] )
ins( i, j, mp[ i ][ j ] );
else
for( int k = 1 ; k <= 9 ; k++ )
ins( i, j, k );
}
int k = 0;
for( int i = 1 ; i <= 9 ; i++ )
for( int j = 1 ; j <= 9 ; j++ )
if( mp[ i ][ j ] )
{
k++;
int x = head[ i ][ j ][ mp[ i ][ j ] ];
remove( Col[ x ] );
for( int u = R[ x ] ; u ^ x ; u = R[ u ] )
remove( Col[ u ] );
}
dfs( k + 1 );
/*for( int i = 1 ; i <= 9 ; i++, putchar( 10 ) )
{
for( int j = 1 ; j <= 9 ; j++ )
{
putchar( mp[ i ][ j ] + '0' );
if( j % 3 == 0 )
putchar( ' ' );
}
if( i % 3 == 0 ) putchar( 10 );
}*/
for( int i = 1 ; i <= 9 ; i++ )
for( int j = 1 ; j <= 9 ; j++ )
putchar( mp[ i ][ j ] + '0' );
putchar( 10 );
}
}