[Noip2009] Target-form Sudoku t4time limit: 2 sec memory limit: 128 MB
Description
Xiaocheng and Xiaohua are both good students who love mathematics. Recently, they fell in love with the sudoku game, and they wanted to use the sudoku for a better match. But the common Sudoku is too simple for them, so they asked Dr. Z for advice, and Dr. Z took out the "target-shaped Sudoku" he recently invented ", as the question of the two children comparison.
The square of the target-shaped Sudoku is the same as that of the ordinary Sudoku. There are 9 small jiugong grids (separated by thick black lines) in the 9-grid wide × 9-grid-tall big jiugongge ). Some numbers are known in the big nine cells. Based on these numbers, use logical reasoning to enter numbers ranging from 1 to 9 in other spaces. Each number cannot appear in each small cell, and each number cannot appear in each row or column. However, the target-type Sudoku is different from the ordinary Sudoku, that is, each square has a score, and, like a target, the closer the distance from the center, the higher the score. ()
The specific score distribution is as follows: the innermost frame (yellow area) is 10 points, and a circle (Red Area) outside the yellow area is 9 points for each grid, in a circle (blue area), each grid is 8 points. In a circle (brown area) outside the blue area, each grid is 7 points, and the outermost area is a circle (white area) each grid has 6 points, as shown in. The requirement of the competition is that each person must complete a given Sudoku (each given Sudoku may have a different filling method) and strive for a higher total score. The total score is the sum of the score on each square and the product of the number entered on the corresponding lattice when the Sudoku is completed ., In the following target Sudoku game, the total number is 2829. The game rules determine the outcome based on the total score.
Thanks to the competition, xiaocheng found you who are good at programming and asked you to help him find the highest score for the given target-type Sudoku.
Input
There are nine lines in the input file. Each row has nine integers (each number is within the range of 0-9), indicating an unfilled Sudoku square. blank spaces are represented by "0. Each number is separated by a space.
Output
The output file contains one row.
Output the highest score of the target-type Sudoku. If the number is independent, an integer-1 is output.
Sample inputinput i7 0 0 9 0 0 0 0 11 0 0 0 0 5 9 0 00 0 0 2 0 0 0 8 00 0 5 0 2 0 0 0 30 0 0 0 0 0 0 6 4 84 1 3 0 0 0 0 0 0 0 0 0 0 2 0 9 02 0 1 0 6 0 8 0 40 8 0 5 0 4 0 1 2 input ii0 0 0 7 0 2 4 5 39 0 0 0 0 0 07 4 0 0 0 5 0 1 01 9 5 0 8 0 0 0 00 7 0 0 0 0 0 0 2 50 3 0 5 7 9 1 0 80 0 0 6 0 1 0 00 6 0 9 0 0 0 0 0 0 0 0 0 0 0 0 6 sample outputoutput i2829output ii2852hint
[Data Scope]
40% of the data, the number of non-zero data in the DT alone is not less than 30.
80% of the data, the number of non-zero data in the DT alone is not less than 26.
100% of the data, the number of non-zero data in the DT alone is not less than 24.
Source
Noip2009 raise Group
Question: calculate the maximum value of the weights obtained according to this question in all the sudoku filling methods.
Question: I want to fill in all the sudoku, and then take Min. However, normal brute-force search requires strong pruning. Write a bare DLX.
There is no skill, that is, bare DLX.
# Include <cstdio> # include <cstring> # include <iostream> # include <algorithm> # define N 800 # define m 400 # define NN 10000 # define INF 0x3f3f3f3f # define li_sdk 3 # define gi_sdk 9 # define su_sdk 81 using namespace STD; int ts [gi_sdk + 1] [gi_sdk + 1]; const int score [gi_sdk + 1] [gi_sdk + 1] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 6, 6, 6, 6, 6, 6, 6, 6, 6}, {0, 6, 7, 7, 7, 7, 7, 7, 7, 6}, {0, 6, 7, 8, 8, 8, 8, 8, 7, 6}, {0, 6, 7, 8, 9, 9, 9, 8, 7, 6 }, {0, 6, 7, 8, 9, 10, 9, 8, 7, 6}, {0, 6, 7, 8, 9, 9, 8, 7, 6}, {0, 6, 7, 8, 8, 8, 8, 8, 7, 6}, {0, 6, 7, 7, 7, 7, 7, 7, 7, 6}, {0, 6, 6, 6, 6, 6, 6, 6, 6}; struct DLX {int elist, Eline; int ID [gi_sdk + 1] [gi_sdk + 1] [gi_sdk + 1]; int Eid [4] [gi_sdk] [gi_sdk]; bool map [m] [N]; int U [NN], d [NN], L [NN], R [NN], C [NN], V [NN]; int H [N], t [m], CNT, ans; inline void Init () {int I, j, k, _ I, _ j; for (I = 1; I <= gi_sdk; I ++) for (j = 1; j <= gi_sdk; j ++) for (k = 1; k <= gi_sdk; k ++) ID [I] [J] [k] = ++ Eline; for (I = 1; I <= gi_sdk; I ++)/* line */{for (j = 1; j <= gi_sdk; j ++) /* Number */{int A = Eid [0] [I] [J] = ++ elist; For (k = 1; k <= gi_sdk; k ++) /* column */{int B = ID [I] [k] [J]; Map [a] [B] = 1 ;}} for (I = 1; I <= gi_sdk; I ++)/* column */{for (j = 1; j <= gi_sdk; j ++) /* Number */{int A = Eid [1] [I] [J] = ++ elist; For (k = 1; k <= Gi _ SDK; k ++)/* line */{int B = ID [k] [I] [J]; Map [a] [B] = 1 ;}}} for (I = 0; I <li_sdk; I ++) for (j = 0; j <li_sdk; j ++)/* JIU Gong Ge */{for (k = 1; k <= gi_sdk; k ++)/* Number */{int A = Eid [2] [I * li_sdk + J + 1] [k] = ++ elist; for (_ I = 1; _ I <= li_sdk; _ I ++) for (_ j = 1; _ j <= li_sdk; _ j ++) /* lattice interior point */{int B = ID [I * li_sdk + _ I] [J * li_sdk + _ j] [k]; map [a] [B] = 1 ;}}for (I = 1; I <= gi_sdk; I ++) for (j = 1; j <= gi_sdk; j ++)/* point position */{int A = Eid [3] [I] [J] = ++ elist; For (k = 1; k <= gi_sdk; k ++)/* Number of 9 points */{int B = ID [I] [J] [K]; Map [a] [B] = 1 ;}} inline void clear () {ans = CNT = 0; memset (u, 0, sizeof (u); memset (D, 0, sizeof (d); memset (L, 0, sizeof (l); memset (R, 0, sizeof (R); memset (C, 0, sizeof (c); memset (H, 0, sizeof (h); memset (T, 0, sizeof (t);} inline void newnode (int x, int y) {C [++ CNT] = y; V [CNT] = X; T [y] ++; If (! H [x]) H [x] = L [CNT] = R [CNT] = CNT; else l [CNT] = H [X], R [CNT] = R [H [x]; R [H [x] = L [R [H [x] = CNT, H [x] = CNT; U [CNT] = U [Y], d [CNT] = y; U [y] = d [U [y] = CNT ;} inline void remove (int x) {for (INT I = d [X]; I! = X; I = d [I]) {for (Int J = R [I]; J! = I; j = R [J]) {u [d [J] = U [J]; d [U [J] = d [J]; T [C [J] --;} l [R [x] = L [X]; R [L [x] = R [X];} inline void resume (int x) {for (INT I = U [X]; I! = X; I = U [I]) {for (Int J = L [I]; J! = I; j = L [J]) {u [d [J] = J; d [U [J] = J; T [C [J] ++;} l [R [x] = x; R [L [x] = x;} inline void build () {// clear (); int I, j, k; CNT = 4 * su_sdk; for (I = 1; I <= CNT; I ++) {u [I] = d [I] = I; L [I] = L [0], R [I] = 0; L [0] = R [L [0] = I;} for (I = 1; I <= gi_sdk; I ++) for (j = 1; j <= gi_sdk; j ++) {int get = (I-1) * gi_sdk + J-1; If (! TS [I] [J]) {for (k = get * gi_sdk + 1; k <= get * gi_sdk + gi_sdk; k ++) for (INT temp = 1; temp <= elist; temp ++) if (Map [temp] [k]) newnode (K, temp );} else {k = get * gi_sdk + ts [I] [J]; for (INT temp = 1; temp <= elist; temp ++) if (Map [temp] [k]) newnode (K, temp) ;}} inline void DFS (int w) {If (! R [0]) {ans = max (ANS, W); return;} int S = R [0], W = T [s], I, J; for (I = R [s]; I; I = R [I]) if (T [I] <W) {W = T [I]; S = I ;} remove (s); for (I = d [s]; I! = S; I = d [I]) {int SC = score [(V [I]-1)/su_sdk + 1] [(V [I]-1) /gi_sdk % gi_sdk + 1]; for (j = R [I]; J! = I; j = R [J]) Remove (C [J]); DFS (W + (V [I]-1) % gi_sdk + 1) * SC ); for (j = L [I]; J! = I; j = L [J]) Resume (C [J]) ;}resume (s); Return ;}} DLX; int main () {// freopen ("test. in "," r ", stdin); // freopen (" My. out "," W ", stdout); DLX. init (); For (INT I = 1; I <= gi_sdk; I ++) for (Int J = 1; j <= gi_sdk; j ++) scanf ("% d", & TS [I] [J]); DLX. build (); DLX. DFS (0); printf ("% d \ n", DLX. ans> 0? DLX. ans:-1); Return 0 ;}
[Noip2009] DLX (dancing links)