行数为9*9*9 代表9行9列每个格子9种情况,如果当前格子有数则只建一行
列约束为 9*9+9*9+9*9+9*9
分别为行9数,列9数,9*9的格子每个格子一个数,3*3的格子9个每个格子一个数
#define DeBUG
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <set>
#include <sstream>
#include <map>
#include <list>
#include <bitset>
using namespace std ;
#define zero {0}
#define INF 0x3f3f3f3f
#define EPS 1e-6
#define TRUE true
#define FALSE false
typedef long long LL;
const double PI = acos(-1.0);
//#pragma comment(linker, "/STACK:102400000,102400000")
inline int sgn(double x)
{
return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);
}
#define N 3267
//每个1占用一个编码+列数 m+9*9*9*4
const int head = 0;
int mat[750][350], tor[750], toc[750], dig[750];
char str[100];
int n, m, size, o[1010], s[750], col[N], row[N], u[N], d[N], l[N], r[N];
//将输入条件转化为01矩阵。
bool makegragh()
{
int strnum, i, j, k, qua, pos, num;
scanf("%s", str);//输入
if (strcmp(str, "end") == 0)return false;
memset(mat, 0, sizeof(mat));//建图
n = 1; m = 324; strnum = 0;//初始化行列值
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
qua = (j - 1) / 3 * 3 + (i - 1) / 3 + 1;//
pos = (i - 1) * 9 + j;
if (str[strnum] == '.')
{
for (k = 1; k <= 9; k++)
{
tor[n] = i;
toc[n] = j;
dig[n] = k;
mat[n][(i - 1) * 9 + k] = 1;
mat[n][81 + (j - 1) * 9 + k] = 1;
mat[n][162 + (qua - 1) * 9 + k] = 1;
mat[n++][243 + pos] = 1;
}
}
else
{
tor[n] = i;
toc[n] = j;
num = str[strnum] - '0';
dig[n] = num;
mat[n][(i - 1) * 9 + num] = 1;
mat[n][81 + (j - 1) * 9 + num] = 1;
mat[n][162 + (qua - 1) * 9 + num] = 1;
mat[n++][243 + pos] = 1;
}
strnum++;
}
}
n--;
return true;
}
void Link(int i, int j, int &rowh)
{
s[j]++;
u[size] = u[j];
d[u[j]] = size;
u[j] = size;
d[size] = j;
row[size] = i;
col[size] = j;
if (rowh == -1)
{
l[size] = r[size] = size;
rowh = size;
}
else
{
l[size] = l[rowh];
r[l[rowh]] = size;
r[size] = rowh;
l[rowh] = size;
}
size++;
}
//将01矩阵转化为十字链表,cnt表示结点个数,01矩阵是n行m列的。
void initial()
{
int i, j, rowh;
memset(s, 0, sizeof(s));
for (i = head; i <= m; i++)
{
r[i] = (i + 1) % (m + 1);
l[i] = (i - 1 + m + 1) % (m + 1);
u[i] = d[i] = i;
}
size = m + 1;
for (i = 1; i <= n; i++)
{
rowh = -1;
for (j = 1; j <= m; j++)
if (mat[i][j])
{
Link(i, j, rowh);
}
}
// printf("size=%d\n", size);
}
//删除矩阵中的列及其相应的行
void myremove(const int &cur)
{
l[r[cur]] = l[cur];
r[l[cur]] = r[cur];
for (int i = d[cur]; i != cur; 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]];
}
}
}
//恢复。顺序和remove相反
void myresume(const int &cur)
{
for (int i = u[cur]; i != cur; i = u[i])
{
for (int j = l[i]; j != i; j = l[j])
{
++s[col[j]];
u[d[j]] = j;
d[u[j]] = j;
}
}
l[r[cur]] = cur;
r[l[cur]] = cur;
}
//最原始版本,只需输出一组合法解
bool dfs(const int &k)
{
if (r[head] == head) //不需判断k是否等于N
{
sort(o, o + k);
for (int i = 0; i < k; i++)
printf("%d", dig[o[i]]);
printf("\n");
return true;
}
int ms = INF, cur = 0;
for (int t = r[head]; t != head; t = r[t])
{
if (s[t] < ms)
{
ms = s[t];
cur = t;
}
}
myremove(cur);
for (int i = d[cur]; i != cur; i = d[i])
{
o[k] = row[i];
for (int j = r[i]; j != i; j = r[j])
myremove(col[j]);
if (dfs(k + 1))return true;
for (int j = l[i]; j != i; j = l[j])
myresume(col[j]);
}
myresume(cur);
return false;
}
int main()
{
#ifdef DeBUGs
freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);
#endif
while (makegragh())
{
initial();
dfs(0);
}
return 0;
}