题意:解数独

分析:

完整的数独有四个充要条件:

1.每个格子都有填数字

2.每列都有1~9中的每个数字

3.每行都有1~9中的每个数字

4.每个9宫格都有1~9中的每个数字

可以转化成精确覆盖问题。每行表示一个格子的一种填法,1~81列表示这个格子的位置,82~162列表示这是哪一行的什么数字,163~243列表示这是哪一列的什么数字,244~324列表示这是哪一个九宫格里的什么数字。每行都把四个1填入这四个区间里的对应位置。最后求出这个01矩阵的精确覆盖就是解。

在DFS里删除列的顺序为由左往右时TLE了,由右向左却AC,什么原因???

 #include <cstdio>
#include <cstring>
int U[],D[],L[],R[],row[],col[],cont[];
int X[],Y[],H[],S[],M,N,sz,ans[][];
bool hashr[][],hashc[][],hashp[][];
void init(int m)
{
for(int i = ;i <= m;i++)
{
U[i] = D[i] = i;
L[i + ] = i;
R[i] = i + ;
S[i] = ;
}
R[m] = ;
L[] = m;
sz = m + ;
} void remove(int c)
{
//删除一整列
R[L[c]] = R[c];
L[R[c]] = L[c];
//删除行
for(int i = D[c];i != c;i = D[i])
{
for(int j = R[i];j != i;j = R[j])
{
D[U[j]] = D[j];
U[D[j]] = U[j];
S[X[j]]--;
}
}
} void resume(int c)
{
//恢复一整列
L[R[c]] = c;
R[L[c]] = c;
//恢复行
for(int i = U[c];i != c;i = U[i])
{
for(int j = L[i];j != i;j = L[j])
{
D[U[j]] = j;
U[D[j]] = j;
S[X[j]]++;
}
}
} void ins(int r,int c)
{
S[c]++;
//纵向插入
D[U[c]] = sz;
U[sz] = U[c];
D[sz] = c;
U[c] = sz;
X[sz] = c;
Y[sz] = r;
//横向插入
if(H[r] == -)
{
H[r] = L[sz] = R[sz] = sz;
}
else
{
R[L[H[r]]] = sz;
L[sz] = L[H[r]];
R[sz] = H[r];
L[H[r]] = sz;
}
sz++;
} bool dfs(int k)
{
if(R[] == )
{
return true;
}
else
{
int m = 0xfffffff,num;
for(int i = R[];i != ;i = R[i])
{
if(S[i] == )
{
return false;
}
if(m > S[i])
{
m = S[i];
num = i;
if(m == )
{
break;
}
}
}
remove(num);
for(int i = D[num];i != num;i = D[i])
{
ans[row[Y[i]]][col[Y[i]]] = cont[Y[i]];
for(int j = R[i];j != i;j = R[j])
{
remove(X[j]);
}
if(dfs(k + ))
{
return true;
}
for(int j = L[i];j != i;j = L[j])//恢复顺序改为由左向右居然慢N倍?!
{
resume(X[j]);
}
}
resume(num);
}
return false;
} int main()
{
char input[];
while(scanf("%s",input),input[] != 'e')
{
memset(hashr,false,sizeof(hashr));
memset(hashc,false,sizeof(hashc));
memset(hashp,false,sizeof(hashp));
for(int i = ;i < ;i++)
{
for(int j = ;j < ;j++)
{
if(input[i * + j] != '.')
{
hashr[i][input[i * + j] - ''] = true;
hashc[j][input[i * + j] - ''] = true;
hashp[i / * + j / ][input[i * + j] - ''] = true;
}
}
}
M = * * ;
N = ;
init(M);
for(int i = ;i < ;i++)
{
for(int j = ;j < ;j++)
{
int k;
if(input[i * + j] != '.')
{
k = input[i * + j] - '';
}
else
{
k = ;
}
if(k != )
{
row[N] = i;
col[N] = j;
cont[N] = k;
H[N] = -;
ins(N,i * + j + );//(i,j)位置已填数字
ins(N, + i * + k);//i行已有k
ins(N, + j * + k);//j列已有k
ins(N++, + (i / * + j / ) * + k);//宫格已有k
}
else
{
for(k = ;k <= ;k++)
{
if(!hashr[i][k] && !hashc[j][k] && !hashp[i / * + j / ][k])
{
row[N] = i;
col[N] = j;
cont[N] = k;
H[N] = -;
ins(N,i * + j + );//(i,j)位置已填数字
ins(N, + i * + k);//i行已有k
ins(N, + j * + k);//j列已有k
ins(N++, + (i / * + j / ) * + k);//宫格已有k
}
}
}
}
}
dfs();
for(int i = ;i < ;i++)
{
for(int j = ;j < ;j++)
{
printf("%d",ans[i][j]);
}
}
printf("\n");
}
return ;
}

poj 3074的更多相关文章

  1. POJ 3074 Sudoku (DLX)

    Sudoku Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  2. 搜索(DLX): POJ 3074 3076 Sudoku

    POJ 3074 : Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller ...

  3. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

  4. 【POJ 3074】 Sudoku

    [题目链接] http://poj.org/problem?id=3074 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 转化方法如下 : 我们知道,在一个数独中 : 1. ...

  5. DLX (poj 3074)

    题目:Sudoku 匪夷所思的方法,匪夷所思的速度!!! https://github.com/ttlast/ACM/blob/master/Dancing%20Link%20DLX/poj%2030 ...

  6. POJ 3074 Sudoku DLX精确覆盖

    DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: ...

  7. POJ 3074 Sudoku (Dacing Links)

    推荐一个写数独很好的博客:http://www.cnblogs.com/grenet/p/3163550.html 主要是把九宫格里的元素换到矩阵里面再求解dancing links 网上找的一模版 ...

  8. poj 3074 Sudoku(Dancing Links)

    Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 Descriptio ...

  9. (简单) POJ 3074 Sudoku, DLX+精确覆盖。

    Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...

  10. POJ 3074 Sudoku(算竞进阶习题)

    二进制优化+dfs 话说这题数据中真的丧心病狂..不加inline还过不去.. 因为不会DLX只好用二进制来优化了...万万没想到还是低空飘过 我们在行.列.格分别用一个9位二进制常数来记录什么数能放 ...

随机推荐

  1. 洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)

    题面 传送门 题解 日常敲板子.jpg //minamoto #include<bits/stdc++.h> #define R register #define inline __inl ...

  2. jQuery——表单应用(1)

    实现结果:聚焦表单的input部分时,input格式变更为CSS样式(获取和失去焦点改变样式) HTML: <!DOCTYPE html> <html> <head> ...

  3. 2017杭电多校第七场1011Kolakoski

    Kolakoski Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Tota ...

  4. 使用JS分页 <span> beta 2.0 未封装的分页

    <html> <head> <title>分页</title> <style> #titleDiv{ width:500px; backgr ...

  5. JSP&&EL&&JSTL

    JSP = JAVA + HTML + JSP自身的东西 JSP的脚本         <%!   %>        :翻译成Servlet中的成员内容. 定义变量,方法,类. -- ...

  6. NodeJs学习记录(二)win7下 配置node连接oracle的环境

    2017/01/23 星期一 前言:还没看几眼教程,就开始分配任务,涉及到连oracle数据库,所以顺便把整个环境的配置放上来 安装文件清单(1).node-v6.9.1-x64.msi(2).pyt ...

  7. R语言常用数学函数

    语言的数学运算和一些简单的函数整理如下: 向量可以进行那些常规的算术运算,不同长度的向量可以相加,这种情况下最短的向量将被循环使用.   > x <- 1:4 > a <- 1 ...

  8. Java实现打包文件

    把文件打包到压缩包里 public void zip (String... files) throws IOException { //创建文件打包流对象 ZipOutputStream zos = ...

  9. 02Struts2 环境搭建

    Struts2 环境搭建 1.下载 Apache Struts2 类库 2.建立web工程 3.配置web.xml <?xml version="1.0" encoding= ...

  10. 【转】Go语言入门教程(一)Linux下安装Go

    说明 系统是Ubuntu. 关于安装 下载安装包 当前官方下载地址是https://golang.org/dl/,如果不能访问,请自行FQ,FQ是技术工作者的必备技能. 安装 tar -xzvf go ...