今天早上又在poj看到一个数独题,粘了以前的爆搜T了,就翻出了以前写的4阶数独改了改
DancingLinks就是快
3074 三阶版
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <utility>
#include <map>
#define pb push_back
#define mp make_pair
#define N 1025
#define M 20005
using namespace std;
int U[M] , D[M] , L[M] , R[M], col[M] , row[M];
int cnt , p[N] , s[N] , T;
char t[101];
vector<int> ans;
int V(int x , int y)
{
return ((x / 3) * 3) + (y / 3);
}
#define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i])
void remove(int c)
{
L[R[c]] = L[c] , R[L[c]] = R[c];
FOR(i,D,c) FOR(j,R,i)
U[D[j]] = U[j] , D[U[j]] = D[j] , -- s[col[j]];
}
void resume(int c)
{
FOR(i,U,c) FOR(j,L,i)
U[D[j]] = D[U[j]] = j , ++ s[col[j]];
L[R[c]] = R[L[c]] = c;
}
bool dfs(int d)
{
if (R[0] == 0)
return 1;
int c = R[0];
FOR(i,R,0) if (s[i] < s[c]) c = i;
remove(c);
FOR(i,D,c)
{
ans.pb(row[i]);
FOR(j,R,i) remove(col[j]);
if (dfs(d + 1)) return 1;
FOR(j,L,i) resume(col[j]);
ans.pop_back();
}
resume(c);
return 0;
}
void initmatrix()
{
int i , j , x , y , z , v , opt[4];
cnt = 325;
for (i = 0 ; i < cnt ; ++ i)
L[i] = i - 1 , R[i] = i + 1 , p[i] = i , s[i] = 0;
L[0] = 324 , R[324] = 0;
for (i = 0 ; i < 729 ; ++ i)
{
x = i / 81 , y = (i / 9) % 9 , z = i % 9; // (x , y) : A + 'z'
v = V(x , y);
opt[0] = 9 * x + y + 1;
opt[1] = 9 * x + z + 81 + 1;
opt[2] = 9 * y + z + 162 + 1;
opt[3] = 9 * v + z + 243 + 1;
for (j = 0 ; j < 4 ; j ++)
{
L[cnt + j] = cnt + j - 1 , R[cnt + j] = cnt + j + 1;
D[p[opt[j]]] = cnt + j , U[cnt + j] = p[opt[j]] , p[opt[j]] = cnt + j;
col[cnt + j] = opt[j] , row[cnt + j] = i , ++ s[opt[j]];
}
L[cnt] = cnt + 3 , R[cnt + 3] = cnt;
cnt += 4;
}
for (i = 0 ; i < 325 ;i ++)
D[p[i]] = i , U[i] = p[i];
}
bool work()
{
int i , j , x , y , z , v;
ans.clear();
char str[12][12] = {};
if (++ T != 1) puts("");
initmatrix();
for (i = 0 ; i < 9 ; ++ i)
for (j = 0 ; j < 9 ; ++ j)
str[i][j] = t[i * 9 + j];
for (x = 0 ; x < 9 ; ++ x)
for (y = 0 ; y < 9 ; ++ y)
if (str[x][y] != '.')
{
z = str[x][y] - '1';
v = V(x , y);
remove(9 * x + y + 1) , remove(9 * x + z + 81 + 1) , remove(9 * y + z + 162 + 1) , remove(9 * v + z + 243 + 1);
}
dfs(0);
for (i = ans.size() - 1 ; i >= 0 ; -- i)
x = ans[i] , str[x / 81][(x / 9) % 9] = '1' + (x % 9);
for (i = 0 ; i < 9 ; ++ i)
printf("%s",str[i]);
return 0;
}
int main()
{
while(scanf("%s" , t) , *t != 'e') work();
return 0;
}
3076 4阶版
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <utility>
#include <map>
#define pb push_back
#define mp make_pair
#define N 1025
#define M 20005
using namespace std;
int U[M] , D[M] , L[M] , R[M], col[M] , row[M];
int cnt , p[N] , s[N] , T;
vector<int> ans;
int V(int x , int y)
{
return ((x >> 2) << 2) + (y >> 2);
}
#define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i])
void remove(int c)
{
L[R[c]] = L[c] , R[L[c]] = R[c];
FOR(i,D,c) FOR(j,R,i)
U[D[j]] = U[j] , D[U[j]] = D[j] , -- s[col[j]];
}
void resume(int c)
{
FOR(i,U,c) FOR(j,L,i)
U[D[j]] = D[U[j]] = j , ++ s[col[j]];
L[R[c]] = R[L[c]] = c;
}
bool dfs(int d)
{
if (R[0] == 0)
return 1;
int c = R[0];
FOR(i,R,0) if (s[i] < s[c]) c = i;
remove(c);
FOR(i,D,c)
{
ans.pb(row[i]);
FOR(j,R,i) remove(col[j]);
if (dfs(d + 1)) return 1;
FOR(j,L,i) resume(col[j]);
ans.pop_back();
}
resume(c);
return 0;
}
void initmatrix()
{
int i , j , x , y , z , v , opt[4];
cnt = 1025;
for (i = 0 ; i < 1025 ; ++ i)
L[i] = i - 1 , R[i] = i + 1 , p[i] = i , s[i] = 0;
L[0] = 1024 , R[1024] = 0;
for (i = 0 ; i < 4096 ; ++ i)
{
x = i >> 8 , y = (i >> 4) & 0xf , z = i & 0xf; // (x , y) : A + 'z'
v = V(x , y);
opt[0] = 16 * x + y + 1;
opt[1] = 16 * x + z + 256 + 1;
opt[2] = 16 * y + z + 512 + 1;
opt[3] = 16 * v + z + 768 + 1;
for (j = 0 ; j < 4 ; j ++)
{
L[cnt + j] = cnt + j - 1 , R[cnt + j] = cnt + j + 1;
D[p[opt[j]]] = cnt + j , U[cnt + j] = p[opt[j]] , p[opt[j]] = cnt + j;
col[cnt + j] = opt[j] , row[cnt + j] = i , ++ s[opt[j]];
}
L[cnt] = cnt + 3 , R[cnt + 3] = cnt;
cnt += 4;
}
for (i = 0 ; i < 1025 ;i ++)
D[p[i]] = i , U[i] = p[i];
}
bool work()
{
int i , j , x , y , z , v;
ans.clear();
char str[16][20];
if (!~scanf("%s\n",str[0]))
return 1;
if (++ T != 1) puts("");
initmatrix();
for (i = 1 ; i < 16 ; ++ i)
scanf("%s\n",str[i]);
for (x = 0 ; x < 16 ; ++ x)
for (y = 0 ; y < 16 ; ++ y)
if (str[x][y] != '-')
{
z = str[x][y] - 'A';
v = V(x , y);
remove(16 * x + y + 1) , remove(16 * x + z + 256 + 1) , remove(16 * y + z + 512 + 1) , remove(16 * v + z + 768 + 1);
}
dfs(0);
for (i = ans.size() - 1 ; i >= 0 ; -- i)
x = ans[i] , str[x >> 8][(x >> 4) & 0xf] = 'A' + (x & 0xf);
for (i = 0 ; i < 16 ; ++ i)
printf("%s\n",str[i]);
return 0;
}
int main()
{
while(1) if(work()) break;
return 0;
}