题目大意:

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\n" , 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\n" , dlx.minv);
174     }
175 
176     return 0;
177 }

 

 posted on 2015-05-18 23:25  Love风吟  阅读(158)  评论(0编辑  收藏  举报