say in front
Pointer implementations are sometimes really inconvenient ...
When an array is implemented, the subscript can represent both a value and a position
However, the pointer can only point to the address, or one more access, or open a separate domain to save = =
How to think the pointers are not excellent ah ...
However, the actual test is still very fast, at least not to be violently trampled hhhhh
Write this dance chain, from 8 o'clock in the morning to 4 o'clock in the afternoon, from their own yy to the back had to refer to someone else's program ...
Because the implementation is more complex, in order to make the program become more "generic", tampering with the original algorithm of a small place, write to the back to find that it can not write down ... So look at others, just follow the process of thinking of the program to modify their own ...
Sure enough to think too much, I think it is a better way, in fact, it is not so ... Topic
Logu P1784 Transfer Door problem
Give a blank sudoku, output a completed Sudoku input output format
Input format:
Enter a 9∗9 9*9 numeric matrix containing 0~9, if 0 at that location, to be filled
Output format:
Outputs a 9∗9 9*9 numeric matrix that represents a completed Sudoku solution
Dancing links solves the problem of precision coverage, which requires the conversion of Sudoku problems into precision coverage issues.
The constraints of Sudoku: Each lattice has and only one number in each row, 0~9 each number appears and appears only once in each column, 0~9 each number appears and appears only once in each house, 0~9 each number appears and appears only once
This TM is obviously a precision coverage problem, it can be directly opened Gan The following is the code with a large constant
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
int id[10][10], cid[10][10], rid[10][10], mid[10][10], bel[10][10];
int rcnt, rmean[1000];
struct node{Node *lf, *rg, *up, *dn, *col;
int Rnum, cnum, ccnt;
}W[5005], *c[350], *r[1000], *head, *tw = w;
void Insert (int r_, int c_) {Node *nd = ++TW;
C[c_]->ccnt + +;
Nd->rnum = r_, Nd->cnum = c_, Nd->col = c[c_]; Nd->up = C[c_]->up;
ND->DN = c[c_]; C[c_]->up->dn = nd;
C[c_]->up = nd; if (!
R[r_]) {r[r_] = nd;
R[R_]->LF = R[R_]->RG = R[r_];
else {nd->lf = r[r_]->lf, Nd->rg = R[r_];
R[r_]->lf->rg = nd, r[r_]->lf = nd; } void Insertline (int i, int j, int x) {rcnt + +;
RMEAN[RCNT] = x;
Insert (rcnt, id[i][j]);
Insert (rcnt, rid[i][x]);
Insert (rcnt, cid[j][x]); Insert (rcnt, mid[bel[i][j]][x] ) ;
} void init () {int tmp = 0; for (int i = 1; I <= 9; i + +) for (int j = 1; J <= 9; j + +) Id[i][j] = ++tmp, rid[i][j] =
ID[I][J] + Bayi, cid[i][j] = Rid[i][j] + Bayi, mid[i][j] = cid[i][j] + 81; for (int i = 1; I <= 9; i + +) {for (int j = 1; J <= 9; j + +) Bel[i][j] = (i-1)/3 * 3
+ (j + 2)/3;
head = ++TW;
for (int i = 1; I <= 324 i + +) c[i] = ++tw, c[i]->ccnt = 0, c[i]->cnum = i;
for (int i = 1; I <= 324 i + +) {c[i]->up = C[I]->DN = C[i];
C[I]->RG = c[i+1], C[I]->LF = c[i-1];
} C[0] = r[0] = head;
C[1]->LF = head, Head->rg = c[1];
C[324]->rg = head, HEAD->LF = c[324];
} void Remove (Node *nd) {nd->lf->rg = Nd->rg;
ND->RG->LF = ND->LF; for (node *i = nd->dn I!= nd i = i->dn) {for (node *j = I->RG; J!= i; j = J->RG) {j->col->ccnt-;
J->up->dn = j->dn, j->dn->up = J->up; }} void Resume (node *nd) {for (node *i = nd->up i!= nd. i = i->up) {for (node *j = i-> LF; J!= I;
j = j->lf) {j->col->ccnt + +;
J->up->dn = J, j->dn->up = j;
} nd->lf->rg = nd;
ND->RG->LF = nd;
int sta[10005], Topp, ans[10][10];
void print () {sort (sta + 1, STA + Topp + 1); for (int i = 1, tmp = 0; I <= 9; i + +) {for (int j = 1; J <= 9; j + +) tmp +, printf ("%
D ", rmean[Sta[tmp]]);
Puts ("");
BOOL Solve () {if (Head->rg = = head) {print ();
Node *now = Head->rg;
for (Node *tmp = NOW->RG, tmp!= Head, TMP = TMP->RG) if (tmp->ccnt < now->ccnt) now = tmp;
Remove (now); for (Node *i = NOW->DN; I!= now; i = I->DN) {//Currently Select line I for (Node *j = i->rg J!= i; j = j->rg)//All I rows have elements, no other rows can have remove (j
->COL);
Sta[++topp] = I->rnum;
if (solve ()) return true;
Topp--;
for (Node *j = i->lf J!= i; j = j->lf) resume (J->col);
} resume (now);
return false;
int main () {init ();
for (int i = 1, x; I <= 9; i + +) {for (int j = 1; J <= 9; j + +) {scanf ("%d", &x);
if (!x) {for (int k = 1; k <= 9; k + +) Insertline (I, J, K);
else Insertline (i, J, X);
} solve (); }//* 8 0 0 0 0 0 0 0 0 0 0 3 6 0 0 0 0 0 0 7 0 0 9 0 2 0 0 0 5 0 0 0 7 0 0 0 A- 0 1 0 0 0 0 6 8 0 0 8 5 0 0 0 1 0 0 9 0 0 0 0 4 0 * * *
Summary
This so-called "dancing Links x" algorithm, in fact, is also a burst search, but also for accurate coverage of the problem of the search, only in the original X algorithm based on the use of multiple tables (two-bit list) for optimization.
And for the Sudoku problem, may still be the violence to some good, less space, short code and good writing, in fact, the search is not much. DLX, if not optimized, but slow to explode, a slow line sample simply can't run out. So, use =w= carefully.
(On the multiple tables, in the "Data structure and algorithm analysis-C language Description," 42nd page mentioned that there should be a lot of information on the Internet)