Language:
Sudoku
Description
A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the first 16 capital letters of the English alphabet), as shown in figure 1a. The game is to fill all the empty grid cells with letters from A to P such that each letter from the grid occurs once only in the line, the column, and the 4x4 square it occupies. The initial content of the grid satisfies the constraints mentioned above and guarantees a unique solution.
![]() Write a Sudoku playing program that reads data sets from a text file. Input
Each data set encodes a grid and contains 16 strings on 16 consecutive lines as shown in figure 2. The i-th string stands for the i-th line of the grid, is 16 characters long, and starts from the first position of the line. String characters are from the set {A,B,…,P,-}, where – (minus) designates empty grid cells. The data sets are separated by single empty lines and terminate with an end of file.
Output
The program prints the solution of the input encoded grids in the same format and order as used for input.
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 |
今天又看了一遍,想明白了
行表示r行c列要填的是v,列表示的是要满足的状态,slot表示a行b列要有字母,row表示a行要有字母b,col表示a列要有字母b。sub表示子矩阵a要有字母b,这样就把数独问题转化成了精确覆盖问题,共有16*16*16行,16*16*4列,前16*16列表示slot,以此类推。这样进行编码的时候,就相当于进行16进制转化
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=16*16*16+10;
const int maxm=16*16*4+10;
const int maxnode=maxn*maxm;
const int SIGMA_SIZE=16;
const int SLOT=0;
const int ROW=1;
const int COL=2;
const int SUB=3;
char s[20][20];
struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],L[maxnode],R[maxnode];
int H[maxn],S[maxm];
int row[maxnode],col[maxnode];
int ansd,ans[maxnode];
void init(int N,int M)
{
n=N,m=M;
ansd=-1;
for(int i=0;i<=m;i++)
{
U[i]=D[i]=i;
L[i]=i-1;
R[i]=i+1;
}
L[0]=m;
R[m]=0;
size=m;
memset(S,0,sizeof(S));
memset(H,-1,sizeof(H));
}
void Link(int r,int c)
{
++S[col[++size]=c];
row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<0)H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
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[col[j]];
}
}
}
void restore(int c)
{
for(int i=U[c];i!=c;i=U[i])
{
for(int j=L[i];j!=i;j=L[j])
{
U[D[j]]=D[U[j]]=j;
++S[col[j]];
}
}
L[R[c]]=R[L[c]]=c;
}
bool Dance(int d)
{
if(R[0]==0)
{
ansd=d;
return true;
}
int c=R[0];
for(int i=R[0];i;i=R[i])
if(S[i]<S[c])c=i;
remove(c);
for(int i=D[c];i!=c;i=D[i])
{
ans[d]=row[i];
for(int j=R[i];j!=i;j=R[j])remove(col[j]);
if(Dance(d+1))return true;
for(int j=L[i];j!=i;j=L[j])restore(col[j]);
}
restore(c);
return false;
}
}dlx;
int encode(int a,int b,int c)
{
return a*256+b*16+c+1;//加2是为了保证,DLX中行编号是从1开始
}
void decode(int code,int &a,int &b,int &c)
{
code--;
c=code%16;code/=16;
b=code%16;code/=16;
a=code;
}
int main()
{
bool first=true;
while(scanf("%s",s[0])!=EOF)
{
if(first)first=false;
else printf("\n");
for(int i=1;i<16;i++)
scanf("%s",s[i]);
dlx.init(16*16*16,16*16*4);
for(int r=0;r<16;r++)
for(int c=0;c<16;c++)
for(int v=0;v<16;v++)
if(s[r][c]=='-'||s[r][c]=='A'+v)
{
int row=encode(r,c,v);
dlx.Link(row,encode(SLOT,r,c));
dlx.Link(row,encode(ROW,r,v));
dlx.Link(row,encode(COL,c,v));
dlx.Link(row,encode(SUB,(r/4)*4+c/4,v));
}
dlx.Dance(0);
for(int i=0;i<dlx.ansd;i++)
{
int r,c,v;
decode(dlx.ans[i],r,c,v);
s[r][c]='A'+v;
}
for(int i=0;i<16;i++)
printf("%s\n",s[i]);
}
return 0;
}
Language:
Sudoku
Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns. Input The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”. Output For each test case, print a line representing the completed Sudoku puzzle. Sample Input .2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534. ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3. end Sample Output 527389416819426735436751829375692184194538267268174593643217958951843672782965341 416837529982465371735129468571298643293746185864351297647913852359682714128574936 |
下面是9*9的,注意他们之间细微的差别
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=9*9*9+10;
const int maxm=9*9*4+10;
const int maxnode=maxn*maxm;
const int SIGMA_SIZE=9;
const int SLOT=0;
const int ROW=1;
const int COL=2;
const int SUB=3;
char s[90];
struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],L[maxnode],R[maxnode];
int H[maxn],S[maxm];
int row[maxnode],col[maxnode];
int ansd,ans[maxnode];
void init(int N,int M)
{
n=N,m=M;
for(int i=0;i<=m;i++)
{
U[i]=D[i]=i;
L[i]=i-1;
R[i]=i+1;
}
L[0]=m;
R[m]=0;
size=m;
memset(S,0,sizeof(S));
memset(H,-1,sizeof(H));
}
void Link(int r,int c)
{
++S[col[++size]=c];
row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<0)H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
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[col[j]];
}
}
}
void restore(int c)
{
for(int i=U[c];i!=c;i=U[i])
{
for(int j=L[i];j!=i;j=L[j])
{
U[D[j]]=D[U[j]]=j;
++S[col[j]];
}
}
L[R[c]]=R[L[c]]=c;
}
bool Dance(int d)
{
if(R[0]==0)
{
ansd=d;
return true;
}
int c=R[0];
for(int i=R[0];i;i=R[i])
if(S[i]<S[c])c=i;
remove(c);
for(int i=D[c];i!=c;i=D[i])
{
ans[d]=row[i];
for(int j=R[i];j!=i;j=R[j])remove(col[j]);
if(Dance(d+1))return true;
for(int j=L[i];j!=i;j=L[j])restore(col[j]);
}
restore(c);
return false;
}
}dlx;
int encode(int a,int b,int c)
{
return a*81+b*9+c;
}
void decode(int code,int &a,int &b,int &c)
{
code--;
c=code%9;code/=9;
b=code%9;code/=9;
a=code;
}
int main()
{
while(scanf("%s",s)!=EOF)
{
if(!strcmp(s,"end"))break;
dlx.init(9*9*9,9*9*4);
for(int r=0;r<SIGMA_SIZE;r++)
for(int c=0;c<SIGMA_SIZE;c++)
for(int v=1;v<=SIGMA_SIZE;v++)
if(s[r*9+c]=='.'||s[r*9+c]=='0'+v)
{
int row=encode(r,c,v);
dlx.Link(row,encode(SLOT,r,c)+1);
dlx.Link(row,encode(ROW,r,v));
dlx.Link(row,encode(COL,c,v));
dlx.Link(row,encode(SUB,(r/3)*3+c/3,v));
}
dlx.Dance(0);
for(int i=0;i<dlx.ansd;i++)
{
int r,c,v;
decode(dlx.ans[i],r,c,v);
s[r*9+c]='1'+v;
}
printf("%s\n",s);
}
return 0;
}