题目大意:
9宫格每个位置都有对应的分数,填完数独后根据对应位置的分数相加之和求个最大值,不存在输出-1
说什么用位运算加速可以解决问题,但是对着标程还是T,最近学了dlx,发现这样解决数独快了很多
位运算加速我确实写不出了,直接用dlx来做这道题目
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <queue> 6 #include <climits> 7 #include <cmath> 8 9 using namespace std; 10 #define N 1000 11 #define MAXNODE 1000000 12 const int INF = INT_MAX; 13 const double eps = 1e-8; 14 15 int a[10][10]; 16 char str[5]; 17 18 int belong[9][9] = { 19 {1,1,1,2,2,2,3,3,3}, 20 {1,1,1,2,2,2,3,3,3}, 21 {1,1,1,2,2,2,3,3,3}, 22 {4,4,4,5,5,5,6,6,6}, 23 {4,4,4,5,5,5,6,6,6}, 24 {4,4,4,5,5,5,6,6,6}, 25 {7,7,7,8,8,8,9,9,9}, 26 {7,7,7,8,8,8,9,9,9}, 27 {7,7,7,8,8,8,9,9,9}, 28 }; 29 int sc[9][9] = { 30 {6,6,6,6,6,6,6,6,6}, 31 {6,7,7,7,7,7,7,7,6}, 32 {6,7,8,8,8,8,8,7,6}, 33 {6,7,8,9,9,9,8,7,6}, 34 {6,7,8,9,10,9,8,7,6}, 35 {6,7,8,9,9,9,8,7,6}, 36 {6,7,8,8,8,8,8,7,6}, 37 {6,7,7,7,7,7,7,7,6}, 38 {6,6,6,6,6,6,6,6,6}, 39 }; 40 41 42 void printM() 43 { 44 for(int i=0 ; i<9 ; i++) 45 for(int j=0 ; j<9 ; j++){ 46 if(j<8) printf("%d " , a[i][j]); 47 else printf("%d " , a[i][j]); 48 } 49 } 50 51 struct DLX{ 52 int n ,m , size; 53 int col[MAXNODE] , row[MAXNODE]; 54 int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE]; 55 int cnt_col[N] , first[N]; 56 int ans[100] , minv; 57 58 void init(int _n , int _m) 59 { 60 n = _n , m = _m; 61 size= m ; 62 for(int i=0 ; i<=m ; i++){ 63 L[i] = i-1 , R[i] = i+1; 64 U[i] = D[i] = i; 65 } 66 L[0] = m , R[m] = 0; 67 for(int i=1 ; i<=m ; i++) cnt_col[i] = 0; 68 for(int i=1 ; i<=n ; i++) first[i] = -1; 69 minv = 0; 70 } 71 72 void link(int r , int c) 73 { 74 ++size; 75 U[D[c]] = size , D[size] = D[c]; 76 U[size] = c , D[c] = size; 77 78 if(first[r]<0) L[size]=R[size]=first[r] = size; 79 else{ 80 L[R[first[r]]] = size , R[size] = R[first[r]]; 81 L[size] = first[r] , R[first[r]] = size; 82 } 83 row[size] = r , col[size] = c , cnt_col[c]++; 84 } 85 86 void Remove(int c) 87 { 88 L[R[c]] = L[c] , R[L[c]] = R[c]; 89 for(int i=D[c] ; i!=c ; i=D[i]){ 90 for(int j=R[i] ; j!=i ; j=R[j]){ 91 U[D[j]] = U[j] , D[U[j]] = D[j]; 92 cnt_col[col[j]]--; 93 } 94 } 95 } 96 97 void Resume(int c) 98 { 99 for(int i=U[c] ; i!=c ; i=U[i]){ 100 for(int j=L[i] ; j!=i ; j=L[j]){ 101 U[D[j]] = D[U[j]] = j; 102 cnt_col[col[j]]++; 103 } 104 } 105 // printM(); 106 L[R[c]] = R[L[c]] = c; 107 } 108 109 void Dance(int d) 110 { 111 if(!R[0]){ 112 int v = 0; 113 for(int i=0 ; i<d ; i++){ 114 int r = (ans[i]-1)/81; 115 int c = ((ans[i]-1)%81)/9; 116 a[r][c] = ((ans[i]-1)%9)+1; 117 v+=a[r][c]*sc[r][c]; 118 } 119 minv=max(minv , v); 120 return; 121 } 122 int st=R[0]; 123 for(int i=R[0] ; i!=0 ; i=R[i]) 124 if(cnt_col[i]<cnt_col[st]) 125 st = i; 126 Remove(st); 127 for(int i=D[st] ; i!=st ; i=D[i]){ 128 ans[d] = row[i]; 129 for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]); 130 Dance(d+1); 131 for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]); 132 } 133 Resume(st); 134 return ; 135 } 136 137 }dlx; 138 139 140 int main() 141 { 142 // freopen("a.in" , "r" , stdin); 143 int T; 144 scanf("%d" , &T); 145 while(T--) 146 { 147 for(int i=0 ; i<9 ; i++){ 148 for(int j=0 ; j<9 ; j++){ 149 scanf("%d" , &a[i][j]); 150 } 151 } 152 dlx.init(729 , 324); 153 for(int i=0 ; i<9 ; i++) 154 for(int j=0 ; j<9 ; j++) 155 { 156 if(a[i][j]){ 157 dlx.link((i*9+j)*9+a[i][j] , i*9+a[i][j]); 158 dlx.link((i*9+j)*9+a[i][j] , 81+j*9+a[i][j]); 159 dlx.link((i*9+j)*9+a[i][j] , 162+(belong[i][j]-1)*9+a[i][j]); 160 dlx.link((i*9+j)*9+a[i][j] , 243+i*9+j+1); 161 } 162 else{ 163 for(int k=1 ; k<=9 ; k++){ 164 dlx.link((i*9+j)*9+k , i*9+k); 165 dlx.link((i*9+j)*9+k , 81+j*9+k); 166 dlx.link((i*9+j)*9+k , 162+(belong[i][j]-1)*9+k); 167 dlx.link((i*9+j)*9+k , 243+i*9+j+1); 168 } 169 } 170 } 171 dlx.Dance(0); 172 if(!dlx.minv) puts("-1"); 173 else printf("%d " , dlx.minv); 174 } 175 176 return 0; 177 }