CSU 1605 数独

 题目大意:

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 }

 

你可能感兴趣的:(su)