hdu1426 Sudoku Killer

简单的DFS,将所有未填的位置依次保存起来,之后,对每一个未填的位置依次枚举,往下搜即可

;;

本来想用DLX的做的,hdu3111是过了,可是原先那个模板在这道题里就是超时,不解啊,换一个模板就过了、

DFS版

#include<stdio.h>
struct point
{
int x, y;
} p[81];
int num, flag, map[10][10];
int judge(int n, int k)
{
int i, j, x, y;
for(i = 0; i < 9; i++)
{
if(i != p[n].y && map[p[n].x][i] == k)
return 0;
if(i != p[n].x && map[i][p[n].y] == k)
return 0;
}
x = p[n].x / 3 * 3;
y = p[n].y / 3 * 3;
for(i = 0; i < 3; i++)
for(j = 0; j < 3; j++)
if(map[x+i][y+j] == k && (i != p[n].x || j != p[n].y))
return 0;
return 1;
}
void dfs(int n)
{
int i;
if(n == num)
{
flag = 1;
return;
}
for(i = 1; i < 10; i++)
{
if(judge(n, i))
{
map[p[n].x][p[n].y] = i;
dfs(n + 1);
if(flag)
return;
map[p[n].x][p[n].y] = 0;
}
}
return;
}
int main()
{
int i, j, t = 0;
char s[2];
while(scanf("%s", s) != -1)
{
num = flag = 0;
if(s[0] == '?')
p[num].x = 0, p[num++].y = 0, map[0][0] = 0;
else
map[0][0] = s[0] - '0';
for(i = 0; i < 9; i++)
for(j = 0; j < 9; j++)
if(i || j)
{
scanf("%s", s);
if(s[0] == '?')
p[num].x = i, p[num++].y = j, map[i][j] = 0;
else
map[i][j] = s[0] - '0';
}
dfs(0);
if(t++)
printf("\n");
for(i = 0; i < 9; i++)
{
for(j = 0; j < 8; j++)
printf("%d ", map[i][j]);
printf("%d\n", map[i][8]);
}
}
return 0;
}
DLX
#include<stdio.h>
#include<string.h>
#define INF 1000000000
const int N = 9;
const int mn = N * N * N *(N * N * N * 4) + N;
const int nn = N * N * N + N;
int U[mn], D[mn], L[mn], R[mn], C[mn], X[mn];
int H[nn], Q[nn], S[nn], vis[nn], size;
int a[nn][nn], ans[nn][nn];
void prepare(int r, int c)
{
int i;
for(i = 0; i <= c; i ++)
{
S[i] = 0;
U[i] = D[i] = i;
R[i] = i + 1;
L[i + 1] = i;
}
R[c] = 0;
size = c;
while(r)
H[r --] = -1;
}
void place(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k)
{
r = (i * N + j) * N + k;
c1 = i * N + j + 1;
c2 = N * N + i * N + k;
c3 = 2 * N * N + j * N + k;
c4 = 3 * N * N + ((i / 3) * 3 + j / 3) * N + k;
}
void link(int r, int c)
{
size ++;
C[size] = c;
S[c] ++;
X[size] = r;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r] < 0)
{
H[r] = size;
L[size] = 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)
{
int i, j;
L[R[c]] = L[c];
R[L[c]] = R[c];
for(i = D[c]; i != c; i = D[i])
for(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)
{
int i, j;
for(i = U[c]; i != c; i = U[i])
for(j = L[i]; j != i; j = L[j])
{
U[D[j]] = j;
D[U[j]] = j;
S[C[j]] ++;
}
R[L[c]] = c;
L[R[c]] = c;
}
int dance(int cur)
{
int i, j, c, temp;
if(!R[0])
{
for(i = 0; i < cur ;i ++)
{
int x = (X[Q[i]] - 1) / N / N;
int y = (X[Q[i]] - 1) / N % N;
ans[x][y] = (X[Q[i]] - 1) % N + 1;
}
return 1;
}
temp = INF;
for(i = R[0]; i != 0; i = R[i])
if(S[i] < temp)
{
temp = S[i];
c = i;
}
remove(c);
for(i = D[c]; i != c; i = D[i])
{
Q[cur] = i;
for(j = R[i] ; j != i; j = R[j])
remove(C[j]);
if(dance(cur + 1))
return 1;
for(j = L[i]; j != i; j = L[j])
resume(C[j]);
}
resume(c);
return 0;
}
int init()
{
int i, j, k, r, c1, c2, c3, c4;
char temp[5];
if(scanf("%s", temp) != 1)
return 0;
a[0][0] = (temp[0] == '?' ? 0 : temp[0] - '0');
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
{
if(!i && !j)
continue;
scanf("%s", temp);
a[i][j] = (temp[0] == '?' ? 0 : temp[0] - '0');
}
prepare(N * N * N, N * N * 4);
memset(vis, 0, sizeof(vis));
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
if(a[i][j])
{
place(r, c1, c2, c3, c4, i, j, a[i][j]);
link(r, c1), link(r, c2), link(r, c3), link(r, c4);
vis[c2] = vis[c3] = vis[c4] = 1;
}
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
if(!a[i][j])
for(k = 1; k <= N; k ++)
{
place(r, c1, c2, c3, c4, i, j, k);
if(vis[c2] || vis[c3] || vis[c4])
continue;
link(r, c1), link(r, c2), link(r, c3), link(r, c4);
}
return 1;
}
void printresult()
{
int i, j;
for(i = 0; i < N; i ++)
{
for(j = 0; j < N; j ++)
{
if(j)
printf(" ");
printf("%d", ans[i][j]);
}
printf("\n");
}
}
int main()
{
int t = 0;
while(init())
{
dance(0);
if(t ++)
printf("\n");
printresult();
}
return 0;
}



原文地址:https://www.cnblogs.com/nanke/p/2363678.html