【POJ】2676 Sudoku 【数独】精确覆盖

来源:互联网 发布:网络的利与弊作文高中 编辑:程序博客网 时间:2024/04/27 07:41

传送门:【POJ】2676 Sudoku 【数独】


题目分析:耶~第一道数独写粗来啦~~~~

数独转化为精确覆盖问题看这篇文章就好啦,我也不多费口舌了大笑

算法实践——舞蹈链(Dancing Links)算法求解数独


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )#define REV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )#define REC( i , A , o ) for ( int i = A[o] ; i != o ; i = A[i] )#define CLR( a , x ) memset ( a , x , sizeof a )const int MAXN = 325 ;const int MAXM = 730 ;const int MAXNODE = 3000 ;const int INF = 0x3f3f3f3f ;struct DLX {int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE] ;int row[MAXNODE] , col[MAXNODE] ;int S[MAXN] , H[MAXM] ;int deep , ans[MAXN] ;int n , m ;int size ;int G[10][10] ;void init () {CLR ( H , -1 ) ;FOR ( i , 0 , n ) {S[i] = 0 ;U[i] = i ;D[i] = i ;L[i] = i - 1 ;R[i] = i + 1 ;}L[0] = n ;R[n] = 0 ;size = n ;}void link ( int r , int c ) {++ size ;++ S[c] ;row[size] = r ;col[size] = c ;U[size] = U[c] ;D[size] = c ;D[U[c]] = size ;U[c] = size ;if ( ~H[r] ) {L[size] = L[H[r]] ;R[size] = H[r] ;L[R[size]] = size ;R[L[size]] = size ;}elseH[r] = L[size] = R[size] = size ;}void remove ( int c ) {L[R[c]] = L[c] ;R[L[c]] = R[c] ;REC ( i , D , c )REC ( j , R , i ) {U[D[j]] = U[j] ;D[U[j]] = D[j] ;-- S[col[j]] ;}}void resume ( int c ) {REC ( i , U , c )REC ( j , L , i ) {++ S[col[j]] ;D[U[j]] = j ;U[D[j]] = j ;}R[L[c]] = c ;L[R[c]] = c ;}int dance ( int d ) {if ( R[0] == 0 ) {deep = d ;return 1 ;}int c = R[0] ;REC ( i , R , 0 )if ( S[c] > S[i] )c = i ;remove ( c ) ;REC ( i , D , c ) {ans[d] = row[i] ;REC ( j , R , i )remove ( col[j] ) ;if ( dance ( d + 1 ) )return 1 ;REC ( j , L , i )resume ( col[j] ) ;}resume ( c ) ;return 0 ;}void solve () {n = 9 * 9 * 4 ;init () ;REP ( i , 0 , 9 )REP ( j , 0 , 9 )scanf ( "%1d" , &G[i][j] ) ;REP ( i , 0 , 9 )REP ( j , 0 , 9 )if ( G[i][j] ) {int r = ( i * 9 + j ) * 9 + G[i][j] ;int c1 = i * 9 + j + 1 ;int c2 = 81 + i * 9 + G[i][j] ;int c3 = 162 + j * 9 + G[i][j] ;int c4 = 243 + ( ( i / 3 ) * 3 + ( j / 3 ) ) * 9 + G[i][j] ;link ( r , c1 ) ;link ( r , c2 ) ;link ( r , c3 ) ;link ( r , c4 ) ;S[c1] = S[c2] = S[c3] = S[c4] = -1 ;}REP ( i , 0 , 9 )REP ( j , 0 , 9 )if ( !G[i][j] )FOR ( k , 1 , 9 ) {int r = ( i * 9 + j ) * 9 + k ;int c1 = i * 9 + j + 1 ;int c2 = 81 + i * 9 + k ;int c3 = 162 + j * 9 + k ;int c4 = 243 + ( ( i / 3 ) * 3 + ( j / 3 ) ) * 9 + k ;if ( ~S[c1] && ~S[c2] && ~S[c3] && ~S[c4] ) {link ( r , c1 ) ;link ( r , c2 ) ;link ( r , c3 ) ;link ( r , c4 ) ;}}dance ( 0 ) ;REP ( i , 0 , deep ) {int key = ( ans[i] - 1 ) % 9 + 1 ;int x = ( ans[i] - 1 ) / 9 / 9 + 1 ;int y = ( ans[i] - 1 ) / 9 % 9 + 1 ;G[x][y] = key ;}FOR ( i , 1 , 9 ) {FOR ( j , 1 , 9 )printf ( "%d" , G[i][j] ) ;printf ( "\n" ) ;}}} dlx ;int main () {int T ;scanf ( "%d" , &T ) ;while ( T -- )dlx.solve () ;return 0 ;}


0 0
原创粉丝点击