POJ 3076 16×16数独

我把代码改得更具通用性了, 你可以试试把XSIZE改成5,那么就是25×25的数独了(阴笑。。。)

 

#include <cstdio> const int XSIZE = 4; const int SIZE = XSIZE * XSIZE; const int WIDTH = 4 * SIZE * SIZE; const int HEIGHT = SIZE * SIZE * SIZE; const int MAXN = WIDTH + 4 * HEIGHT; const int ROW = SIZE * SIZE; const int COL = 2 * SIZE * SIZE; const int BLOCK = 3 * SIZE * SIZE; const int INF = HEIGHT + 10; int C[MAXN+10], L[MAXN+10], R[MAXN+10], U[MAXN+10], D[MAXN+10], S[WIDTH+10], save[WIDTH+10]; char str[SIZE+3], O[SIZE*SIZE]; int flag; void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; for (int i = D[c]; i != c; i = D[i]) { for (int j = R[i]; j != i; j = R[j]) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[C[j]]; } } } void resume(int c) { for (int i = U[c]; i != c; i = U[i]) { for (int j = L[i]; j != i; j = L[j]) { ++S[C[j]]; U[D[j]] = j; D[U[j]] = j; } } L[R[c]] = c; R[L[c]] = c; } void dfs(int k) { if(R[0] == 0) { for(int j = 0; j < SIZE*SIZE; j++) { printf("%c", O[j]); if((j+1)%SIZE == 0) { printf("/n"); } } flag = 1; return; } int s = INF, c; for (int t = R[0]; t != 0; t = R[t]) { if (S[t] < s) { s = S[t]; c = t; } } remove(c); for (int i = D[c]; i != c; i = D[i]) { int x = (i-WIDTH-1)/4; O[x/SIZE] = x%SIZE + 'A'; for (int j = R[i]; j != i; j = R[j]) { remove(C[j]); } dfs(k + 1); for (int k = L[i]; k != i; k = L[k]) { resume(C[k]); } if(flag == 1) { break; } } resume(c); } void insert_node(int& cnt, int col, int head, int& tail) { C[cnt] = col; S[col]++; U[cnt] = U[col]; D[U[col]] = cnt; D[cnt] = col; U[col] = cnt; R[tail] = cnt; L[cnt] = tail; R[cnt] = head; L[head] = cnt; tail = cnt; cnt++; } int main(int argc, char* argv[]) { int i, j, ccnt, cnt, col, head, tail, num, digt, y, len; char x; do{ ccnt = WIDTH; len = 0; flag = 0; for(i = 0; i <= ccnt; i++) { L[i] = i-1; R[i] = i+1; U[i] = D[i] = i; S[i] = 0; } L[0] = ccnt; R[ccnt] = 0; cnt = ccnt+1; for(i = 0; i < HEIGHT; i++) { digt = i % SIZE + 1; num = i / SIZE; x = num / SIZE; y = num % SIZE; head = tail = cnt; col = num + 1; insert_node(cnt, col, head, tail); col = ROW + x*SIZE + digt; insert_node(cnt, col, head, tail); col = COL + y*SIZE + digt; insert_node(cnt, col, head, tail); col = BLOCK + (x/XSIZE*XSIZE+y/XSIZE)*SIZE + digt; insert_node(cnt, col, head, tail); } for(i = 0; i < SIZE; i++) { gets(str); for(j = 0; j < SIZE; j++) { if(str[j] != '-') { x = str[j] - 'A' + 1; int t = i*SIZE + j; O[t] = str[j]; remove(++t); save[len++] = t; remove(t = ROW+i*SIZE+x); save[len++] = t; remove(t = COL+j*SIZE+x); save[len++] = t; remove(t = BLOCK+(i/XSIZE*XSIZE+j/XSIZE)*SIZE+x); save[len++] = t; } } } dfs(0); for(i = len-1; i >= 0; i--) { resume(save[i]); } }while(gets(str) && printf("/n")); return 0; } 

 

下面贴上25×25的一个解:

 

A B C D E F G H I J K L M N O P Q R S T U V W X Y

K L M N O A B C D E P Q R S T V W U X Y F G H I J

F G H I J X Y V U W A B C D E K L M N O P Q R S T

W V U Y X P Q R S T F G H I J A B C D E K L M N O

P Q R S T K L M N O X U W V Y F G H I J A B C D E

C A E B N S P T G K R O U X W H J Y V L D I Q M F

D H J F R C A W X B M V Y L N I P S K Q E O T U G

X O Y G L D E I M F C A P Q B R T N U W H J V K S

I S K T U H V Y Q N D E J G F C A O M B R X P L W

M W Q V P J O U R L H I T K S D E X G F C A N Y B

B E A O C N M Q Y H W P S J R L X K T I G D U F V

G P F K D B R A E C L X Q H V N U W J M T Y S O I

L Y W U H G D F K I B T A E C Q O V R S N M X J P

N T S X I V W J P U G D F O M B Y A E C L H K Q R

Q J V R M L X O T S N Y K U I G D F H P B W A E C

S F D A B Y U K L X T R I W H O N P Q V J E G C M

E M I C G Q H B A D V S X Y K J R T W U O F L P N

O R T W Q E F G C P J N B A D S M I L X V U Y H K

V N L P K R J S O M E F G C U Y H B A D Q T I W X

J U X H Y T I N W V O M L P Q E F G C K S R B A D

R C B E A O T D H Y Q J V M X W K L P N I S F G U

Y D G M F I C P B A S W N T L U V J O H X K E R Q

T K O L S W N E F G U C D B A X I Q Y R M P J V H

H I P Q V U S X J R Y K E F G M C D B A W N O T L

U X N J W M K L V Q I H O R P T S E F G Y C D B A

 

你可能感兴趣的:(POJ 3076 16×16数独)