首先dfs给每个格子分一个大的区块

其次套板子就a

我一开始直接在选取行的时候填数独,发现超时

我这一行也就4个元素,找到 x <= 81 的列计算元素位置,81 < x <= 162 的列计算是什么数字

这就超时了?

后来还是记录每一行的代表的  行和列 和 数字

选区行的时候记录选取的行

最后矩阵为空的时候  一起填入数独

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
//精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1
const int MN = ;//最大行数
const int MM = ;//最大列数
const int MNN = 1e5+; //最大点数
int pl;
int anss[][];
struct node
{
int i,j,val;
};
node p[**+];
struct DLX
{
int n, m, si;//n行数m列数si目前有的节点数
//十字链表组成部分
int U[MNN], D[MNN], L[MNN], R[MNN], Row[MNN], Col[MNN];
//第i个结点的U向上指针D下L左R右,所在位置Row行Col列
int H[MN], S[MM]; //记录行的选择情况和列的覆盖情况
int ansd, ans[MN];
int k = ;
void init(int _n, int _m) //初始化空表
{
n = _n;
m = _m;
k = ;
for (int i = ; i <= m; i++) //初始化第一横行(表头)
{
U[i] = D[i] = i; //目前纵向的链是空的
L[i] = i - ;
R[i] = i + ; //横向的连起来
}
R[m] = ; L[] = m;
si = m; //目前用了前0~m个结点
memset(S, , sizeof(S));
memset(H, -, sizeof(H));
}
void link(int r, int c) //插入点(r,c)
{
++S[Col[++si] = c]; //si++;Col[si]=c;S[c]++;
Row[si] = r;//si该结点的行数为r
D[si] = D[c];//向下指向c的下面的第一个结点
U[D[c]] = si;//c的下面的第一个结点的上面为si
U[si] = c;//si的上面为列指针
D[c] = si;//列指针指向的第一个该列中的元素设为si
if (H[r]<)//如果第r行没有元素
H[r] = L[si] = R[si] = si;
else
{
R[si] = R[H[r]];//si的右边为行指针所指的右边第一个元素
L[R[H[r]]] = si;//行指针所指的右边第一个元素的左侧为si
L[si] = H[r];//si的左侧为行指针
R[H[r]] = si;//行指针的右侧为si
}
}
void rm(int c) //列表中删掉c列
{
L[R[c]] = L[c];//表头操作 //c列头指针的右边的元素的左侧指向c列头指针左边的元素
R[L[c]] = R[c];//c列头指针的左边的元素的右侧指向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 resume(int c) //恢复c列
{
for (int i = U[c]; i != c; i = U[i])//枚举该列元素
for (int j = L[i]; j != i; j = L[j])//枚举该列元素所在的行
++S[Col[U[D[j]] = D[U[j]] = j]];//D[U[j]]=j;U[D[j]]=j;S[Col[j]]++;
L[R[c]] = R[L[c]] = c;//c列头指针左右相连
}
bool dance(int d) //选取了d行
{
if (ansd != - && ansd < d)return ;
if (R[] == )//全部覆盖了
{
k++;
//全覆盖了之后的操作
if(ansd==-)ansd = d;
else if (d < ansd) ansd = d;
/*memcpy(fina,anss,sizeof(anss));
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
printf("%d",anss[i][j]);
printf("\n");
}*/
for(int i = ; i < ansd; ++i)
{
anss[p[ans[i]].i][p[ans[i]].j] = p[ans[i]].val;
}
return ;
}
int c = R[];//表头结点指向的第一个列
for (int i = R[]; i != ; i = R[i])//枚举列头指针
if (S[i]<S[c])//找到列中元素个数最少的
c = i;
rm(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])
rm(Col[j]);//将该列的某个元素的行上的元素所在的列都删去
dance(d + );
if(k == ) return ;
for (int j = L[i]; j != i; j = L[j])
resume(Col[j]); }
resume(c);
return ;
}
};
int s[][];
int kua[][];
int arr[][];
int dx[] = {,,,-};
int dy[] = {-,,,};
int fc[] = {,,,};
DLX di;
void dfs(int x,int y,int cnt);
int main()
{
int t,ppap = ;
scanf("%d",&t);
while(ppap <= t)
{
memset(anss,,sizeof(anss));
for(int i = ; i < ; ++i)
{
for(int j = ; j < ; ++j)
{
scanf("%d",s[i]+j);
}
}
int cnt = ;
memset(kua,,sizeof(kua));
for(int i = ; i < ; ++i)
for(int j = ; j < ; ++j)
{
if(kua[i][j] == )
{
kua[i][j] = cnt;
dfs(i,j,cnt++);
}
}
/*
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
printf("%d ",arr[i][j]);
printf("\n");
}
*/
//----------------------------
di.init(**,**);
for(int i = ; i < ; ++i)
{
for(int j = ; j < ; ++j)
{
//cout << s[cnt];
if(arr[i][j] == )
{
for(int d = ; d <= ; ++d)
{
di.link(i**+j*+d,i*+j+);
di.link(i**+j*+d,i*+d+);
di.link(i**+j*+d,j*+d+);
di.link(i**+j*+d,(kua[i][j]-)*+d+);
p[i**+j*+d].i = i; p[i**+j*+d].j = j; p[i**+j*+d].val = d;
}
}
else
{
int d = arr[i][j];
di.link(i**+j*+d,i*+j+);
di.link(i**+j*+d,i*+d+);
di.link(i**+j*+d,j*+d+);
di.link(i**+j*+d,(kua[i][j]-)*+d+);
p[i**+j*+d].i = i; p[i**+j*+d].j = j; p[i**+j*+d].val = d;
}
}
} di.ansd = -;
di.dance();
printf("Case %d:\n",ppap++);
if(di.ansd == -)
{
printf("No solution\n");
continue;
}
if(di.k != )
{
printf("Multiple Solutions\n");
continue;
}
/*for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
printf("%d",anss[i][j]);
printf("\n");
}*/
for(int i = ; i < ; ++i)
{
for(int j = ; j < ; ++j)
{
printf("%d",anss[i][j]);
}
printf("\n");
}
}
}
void dfs(int x,int y,int cnt)
{
int k = s[x][y];
//cout << x << y << " " << s[x][y]<< endl;
int xx,yy;
for(int i = ; i < ; ++i)
{
xx = x + dx[i];
yy = y + dy[i];
if(k >= fc[i]) {
k-=fc[i];
continue;
}
if(kua[xx][yy] == ){
kua[xx][yy] = cnt;
dfs(xx,yy,cnt);
}
}
arr[x][y] = k;
}

hdu 4069 垃圾数独的更多相关文章

  1. HDU 4069 数独

    好久没做题了,建图搞了好久…… 然后,判是否有多解的时候会把原来的答案覆盖掉…… 这里没注意,弄了一下午…… 代码: #include <iostream> #include <cs ...

  2. HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...

  3. hdu 4069 福州赛区网络赛I DLC ***

    再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...

  4. (中等) HDU 4069 Squiggly Sudoku , DLX+精确覆盖。

    Description Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that ...

  5. [DLX+bfs] hdu 4069 Squiggly Sudoku

    题意: 给你9*9的矩阵.对于每一个数字.能减16代表上面有墙,能减32代表以下有墙. .. 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独, ...

  6. Dancing Links [Kuangbin带你飞] 模版及题解

    学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/762786 ...

  7. Dancing Link专题

    一些链接: http://www.cnblogs.com/-sunshine/p/3358922.html http://www.cnblogs.com/grenet/p/3145800.html 1 ...

  8. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  9. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

随机推荐

  1. Python设计模式 - UML - 对象图(Object Diagram)

    简介 对象图和类图的基本概念是类似的,可以看作类图在系统某一时刻的镜像,显示了该时刻系统中参与交互的各个对象以及它们之间的关系. 对象图的元素包括对象.链接.包,元素之间的关系和类图相似. 对象图建模 ...

  2. 初识Attention机制(NLP领域)

    Attention 机制. 参考:https://blog.csdn.net/xiewenbo/article/details/79382785 要是关注深度学习在自然语言处理方面的研究进展,我相信你 ...

  3. 关于sqlserver使用in不报错问题

    最近使用CI处理接口时自己拼装了个函数,直接把数字implode(',',$arr)之后就放在了in中,发现一直返回空数据,以为数据库就是无匹配的,但是后面发现有对应的数据,多搬检测没发现问题,后面发 ...

  4. 主机WiFi时,vmware ubuntu 桥接上网

    1.在vmwared软件主页的编辑->虚拟网络编辑器中,桥接模式,选择桥接至电脑的无线网卡(在主机上查询) 2.虚拟机设置中,选择桥接模式 3.ubuntu 桌面右上方edit connecti ...

  5. 十、JAVA面试简答

    2.ASCII编码表的常识 3.&和&&,|和||的区别 下面我们就分成三组对问题进行分析:分别是&和&&,|和||及~和!. 1.&是按位与操 ...

  6. Putty6.0 提示Access denied

    1.如果putty能正常使用,解决方法很简单: 只要在Putty的configuration里面Connection->SSH->Auth->GSSAPI的配置中,去掉默认的Atte ...

  7. windows下SVN服务器搭建--VisualSVN与TortoiseSVN的配置安装

    在讲解之前,我们来思考两个问题: 1.什么是版本控制 2.为什么要用版本控制工具 ----------------------------------------------------- 版本控制工 ...

  8. 第5-7次OO作业总结分析

    (1)从多线程的协同和同步控制方面,分析和总结自己三次作业来的设计策略及其变化. 第五次作业 第五次作业是对多线程的初步探索,所以对于多线程的基本书写机制的认识比较多.本次作业难点在于了解多线程的运作 ...

  9. 分布式一致性的基石---Paxos算法(1)

    分布式一致性的基石---Paxos算法(1) Paxos算法是由微软的工程师Lamport提出,Lamport依靠Paxos算法获得图灵奖: Paxos算法旨在解决相互信任的分布式系统中,多个节点能快 ...

  10. robotframework+selenium搭配chrome浏览器,web测试案例(搭建篇)

    这两天发布版本 做的事情有点多,都没有时间努力学习了,先给自己个差评,今天折腾了一天, 把robotframework 和 selenium 还有appnium 都研究了一下 ,大概有个谱,先说说we ...