hdu 4069 垃圾数独
首先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 垃圾数独的更多相关文章
- HDU 4069 数独
好久没做题了,建图搞了好久…… 然后,判是否有多解的时候会把原来的答案覆盖掉…… 这里没注意,弄了一下午…… 代码: #include <iostream> #include <cs ...
- 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 ...
- hdu 4069 福州赛区网络赛I DLC ***
再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...
- (中等) 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 ...
- [DLX+bfs] hdu 4069 Squiggly Sudoku
题意: 给你9*9的矩阵.对于每一个数字.能减16代表上面有墙,能减32代表以下有墙. .. 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独, ...
- Dancing Links [Kuangbin带你飞] 模版及题解
学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/762786 ...
- Dancing Link专题
一些链接: http://www.cnblogs.com/-sunshine/p/3358922.html http://www.cnblogs.com/grenet/p/3145800.html 1 ...
- KUANGBIN带你飞
KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题 //201 ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
随机推荐
- Robot Return to Origin
There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its mov ...
- ES6学习笔记(字符串和数值)
(一)字符串的扩展 1.字符串的遍历 for (let codePoint of 'foo') { console.log(codePoint) } // "f" // " ...
- Ubuntu 清除缓存 apt-get命令参数
整理了Ubuntu Linux操作系统下apt-get命令的详细说明,分享给大家.常用的APT命令参数:apt-cache search package 搜索包apt-cache show packa ...
- 138 条 Vim 命令、操作、快捷键全集
命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...
- ACM学习之路
2018-10-18 11:03:00 今天开始踏上实现梦想的道路,希望自己不要懈怠. 坚持做简单的事,坚持下来就会变得不简单.
- AS3语法和UNITY C#语法的异同
AS3 UNITY Sprite a = new Sprite(); trace(a.paent); 此时a.parent为null,还未AddChild到屏幕上, 一般用这个来判断在不在屏幕上 ...
- pwnable.kr-passcode-witeup
进入远端运行, 废话不多说,下载下来分析. 根据提示,编译一下子. 知道问题了. 想象着,输入的值到了passcode1和passcode2的值作为地址的地方,passcode1处刚输入值时,程序终止 ...
- vue项目中使用less或者sass的方法
半年木有更新博客了... 前段时间一直在学习vue,开始记录一下遇到的问题吧 这篇文章主要是总结一下vue中使用less或者sass的方法,以less为例(style.less) 主要是两种 1.对于 ...
- 关于jqGrid组件表格无法自适应宽度问题
今天生成了一个4列的表格,但是无法自适应宽度,使用 $(window).resize(function(){ $(window).unbind("onresize"); $(&qu ...
- ListView的BeginUpdate()和EndUpdate()作用[z]
[z]https://blog.csdn.net/u011108093/article/details/79448060 许多Windows 窗体控件(例如,ListView 和 TreeView 控 ...