Description
给一个16*16的方格矩阵,每个方格里填‘A’-‘P’的字符。矩阵里会有初始的字符。
满足以下条件:
1. 每一列都出现了‘A’-‘P’的字符。
2. 每一行都出现了‘A’-‘P’的字符。
3. 如下图,沿着粗线把矩阵分割成16个小矩阵,每一个小矩阵都出现了‘A’-‘P’的字符。
Input
共16行,每行16个字符,由大写字符‘A’~‘P’以及‘-’构成,‘-’表示待填项。输入数据保证只有一组解。
Output
输出数独字谜的一组解。
Sample Input
–A—-C—–O-I
-J–A-B-P-CGF-H-
–D–F-I-E—-P-
-G-EL-H—-M-J–
—-E—-C–G—
-I–K-GA-B—E-J
D-GP–J-F—-A–
-E—C-B–DP–O-
E–F-M–D–L-K-A
-C——–O-I-L-
H-P-C–F-A–B—
—G-OD—J—-H
K—J—-H-A-P-L
–B–P–E–K–A-
-H–B–K–FI-C–
–F—C–D–H-N-
Sample Output
FPAHMJECNLBDKOGI
OJMIANBDPKCGFLHE
LNDKGFOIJEAHMBPC
BGCELKHPOFIMAJDN
MFHBELPOACKJGNID
CILNKDGAHBMOPEFJ
DOGPIHJMFNLECAKB
JEKAFCNBGIDPLHOM
EBOFPMIJDGHLNKCA
NCJDHBAEKMOFIGLP
HMPLCGKFIAENBDJO
AKIGNODLBPJCEFMH
KDEMJIFNCHGAOPBL
GLBCDPMHEONKJIAF
PHNOBALKMJFIDCEG
IAFJOECGLDPBHMNK
Dancing Links
给程序:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
const int Slot=0;
const int Row=1;
const int Col=2;
const int Pos=3;
int U[320000],D[320000],L[320000],R[320000],S[1100]; //按理说是应该开4194304=4096*1024的大小,不过既然只有唯一解的话,行数就会相应的小了,开这么大就够了
int ans[300],col[320000],row[320000];//256
char Map[20][20];
char Ans[20][20];
int size=0;
int yama(int a,int b,int c){
return a*256+b*16+c+1;
}
void jiema(int x,int &a,int &b,int &c){
x--;
c=x%16;
x/=16;
b=x%16;
x/=16;
a=x%16;
}
void init(int n){
for(int i=0;i<=n;i++){
L[i]=i-1;R[i]=i+1;U[i]=i;D[i]=i;
}
L[0]=n;
R[n]=0;
size=n+1;
memset(S,0,sizeof(S));
}
void ins(int r,vector<int>Q){
int first=size;
for(int i=0;i<Q.size();i++){
int c=Q[i];
R[size]=size+1;L[size]=size-1;
U[size]=U[c];D[size]=c;
D[U[c]]=size;U[c]=size;
row[size]=r;col[size]=c;
S[c]++;size++;
}
L[first]=size-1;R[size-1]=first;
}
void del(int v){
for(int i=D[v];i!=v;i=D[i])
for(int j=R[i];j!=i;j=R[j]){
U[D[j]]=U[j];
D[U[j]]=D[j];
S[col[j]]--;
}
R[L[v]]=R[v];
L[R[v]]=L[v];
}
void restore(int v){
R[L[v]]=v;
L[R[v]]=v;
for(int i=U[v];i!=v;i=U[i])
for(int j=L[i];j!=i;j=L[j]){
U[D[j]]=j;
D[U[j]]=j;
S[col[j]]++;
}
}
bool dfs(int d){
if(R[0]==0){
return true;
}
int c=R[0];
for(int i=R[0];i!=0;i=R[i])if(S[i]<S[c])c=i;
del(c);
for(int i=U[c];i!=c;i=U[i]){
ans[d]=row[i];
for(int j=R[i];j!=i;j=R[j])del(col[j]);
if(dfs(d+1))return true;
for(int j=L[i];j!=i;j=L[j])restore(col[j]);
}
restore(c);
return false;
}
void print(){
int a,b,c;
for(int i=0;i<256;i++){
jiema(ans[i],a,b,c);
Ans[a][b]=c+'A';
}
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
putchar(Ans[i][j]);
}
putchar('\n');
}
cout<<endl;
}
int main(){
while(scanf("%s",Map[0])!=EOF){
for(int i=1;i<16;i++)
scanf("%s",Map[i]);
vector <int>Q;
init(16*16*4);
for(int i=0;i<16;i++)
for(int j=0;j<16;j++)
for(int k=0;k<16;k++)
if(Map[i][j]=='-'||Map[i][j]=='A'+k){
Q.clear();
Q.push_back(yama(Slot,i,j));
Q.push_back(yama(Row,i,k));
Q.push_back(yama(Col,j,k));
Q.push_back(yama(Pos,(i/4)*4+(j/4),k));
ins(yama(i,j,k),Q);
}
if(dfs(0))print();
}
return 0;
}
学习了。