【UVA1309】Sudoku(DLX)
大致题意: 让你填完整一个\(16*16\)的数独。
解题思路
我们知道,数独问题显然可以用\(DLX\)解决。
考虑对于一个数独,它要满足的要求为:每个位置都必须有数,每一行都必须有全部\(16\)个数,每一列都必须有全部\(16\)个数,每一个\(16\)宫格都必须有全部\(16\)个数。
我们定义一个状态\((i,j,k)\),表示在第\(i\)行第\(j\)列填\(k\)。
对于一种填法它可以同时满足\(4\)种要求中各一种,因此如果把一种填法看作\(DLX\)中的一行,则每一行有\(4\)个\(1\)。
注意,对于已经给出数的位置,我们只能选择给出的那种填法, 否则, 可以选择任意数,有\(16\)种填法。
而对于这\(4\)种限制,每种都要求有\(256\)个,因此\(DLX\)共有\(1024\)列。
然后就可以按此跑\(DLX\)板子了。
具体实现详见代码。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
using namespace std;
char a[20][20];struct Operate {int x,y,v;}p[(1<<12)+5];
class DancingLinksX//DLX模板
{
	private:
		int tot,sz[(1<<10)+5],lnk[(1<<12)+5],res[(1<<8)+5];
		struct node
		{
			int x,y,u,d,l,r;
			I node(CI X=0,CI Y=0,CI U=0,CI D=0,CI L=0,CI R=0):x(X),y(Y),u(U),d(D),l(L),r(R){}
		}O[(1<<14)+5];
		I bool Dance(CI x)
		{
			#define Delete(x)\
			{\
				O[O[O[x].l].r=O[x].r].l=O[x].l;\
				for(RI i=O[x].d;i^x;i=O[i].d) for(RI j=O[i].r;j^i;j=O[j].r)\
					O[O[O[j].u].d=O[j].d].u=O[j].u,--sz[O[j].y];\
			}
			#define Regain(x)\
			{\
				for(RI i=O[x].d;i^x;i=O[i].d) for(RI j=O[i].r;j^i;j=O[j].r)\
					O[O[j].u].d=O[O[j].d].u=j,++sz[O[j].y];\
				O[O[x].l].r=O[O[x].r].l=x;\
			}
			if(!O[0].r)
			{
				RI i;for(i=1;i^x;++i) a[p[res[i]].x][p[res[i]].y]=p[res[i]].v;//更新到数独上
				for(i=1;i<=16;++i) puts(a[i]+1);return 1;//输出
			}
			RI i,j,t=O[0].r;for(i=O[t].r;i;i=O[i].r) sz[t]>sz[i]&&(t=i);
			Delete(t);for(i=O[t].d;i^t;i=O[i].d)
			{
				for(res[x]=O[i].x,j=O[i].r;j^i;j=O[j].r) Delete(O[j].y);
				if(Dance(x+1)) return 1;
				for(j=O[i].l;j^i;j=O[j].l) Regain(O[j].y);
			}Regain(t);return 0;
		}
	public:
		I void Init(CI x)
		{
			RI i;for(tot=x,i=0;i<=x;++i) O[i]=node(0,i,i,i,i-1,i+1);
			O[O[0].l=x].r=0,memset(lnk,-1,sizeof(lnk)),memset(sz,0,sizeof(sz));
		}
		I void Insert(CI x,CI y)
		{
			++sz[y],O[++tot]=node(x,y,y,O[y].d),O[y].d=O[O[y].d].u=tot,
			~lnk[x]?(O[tot].l=lnk[x],O[tot].r=O[lnk[x]].r,O[lnk[x]].r=O[O[lnk[x]].r].l=tot)
			:(lnk[x]=O[tot].l=O[tot].r=tot);
		}
		I void Solve() {Dance(1);}
}DLX;
int main()
{
	RI Ttot,i,j,k,cnt,t=0;W(~scanf("%s",a[1]+1))
	{
		#define P(x,y) ((x-1<<4)+y)
		#define T(x,y) (((x-1>>2)<<2)+(y+3>>2))
		t++&&putchar('\n');//注意输出空行
		for(DLX.Init(1<<10),cnt=0,i=2;i<=16;++i) scanf("%s",a[i]+1);
		for(i=1;i<=16;++i) for(j=1;j<=16;++j) for(k=1;k<=16;++k)
		{
			if(a[i][j]^'-'&&(a[i][j]&31)^k) continue;//对于已经给定的数,必须按这种填法填
			p[++cnt].x=i,p[cnt].y=j,p[cnt].v=64|k,//存下这种填法
			DLX.Insert(cnt,P(i,j)),DLX.Insert(cnt,P(i,k)+256),//每一位要有数、每一行要有全部数
			DLX.Insert(cnt,P(j,k)+512),DLX.Insert(cnt,P(T(i,j),k)+768);//每一列要有全部数、每一16宫格要有全部数
		}DLX.Solve();
	}return 0;
}
【UVA1309】Sudoku(DLX)的更多相关文章
- NoSQL之【MongoDB】学习(三):配置文件说明
		摘要: 继上一篇NoSQL之[MongoDB]学习(一):安装说明 之后,知道了如何安装和启动MongoDB,现在对启动时指定的配置文件(mongodb.conf)进行说明,详情请见官方. 启动Mon ... 
- 【操作系统】进程间通信(C#)
		原文:[操作系统]进程间通信(C#) 08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活.此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xia ... 
- 【Luogu3444】ORK-Ploughing(贪心)
		[Luogu3444]ORK-Ploughing(贪心) 题面 Luogu 题解 我们知道,如果我们选定了以横向为主,或者纵向为主, 那么就有尽可能减少另一个方向上耕地的次数 所以分开贪心,但是本质相 ... 
- 【BZOJ1997】Planar(2-sat)
		[BZOJ1997]Planar(2-sat) 题面 BZOJ 题解 很久没做过\(2-sat\)了 今天一见,很果断的就来切 这题不难呀 但是有个玄学问题: 平面图的性质:边数\(m\)的最大值为\ ... 
- 【Luogu1337】平衡点(模拟退火)
		[Luogu1337]平衡点(模拟退火) 题面 洛谷 题解 和BZOJ3680吊打XXX是一样的.. 但是数据很强呀.. 疯狂调参 各种WA... 很无奈呀.... #include<iostr ... 
- 【BZOJ1996】合唱队(动态规划)
		[BZOJ1996]合唱队(动态规划) 题面 BZOJ 题解 很容易的一道题 因为每个人不是放在了左边就是放在了右边 所以每次放好的人必定是原序列的一个子串 所以,很容易想到区间\(dp\) 设\(f ... 
- 【BZOJ1899】午餐(动态规划)
		[BZOJ1899]午餐(动态规划) 题面 BZOJ 题解 我太弱了 这种\(dp\)完全做不动.. 首先,感性理解一些 如果所有人都要早点走, 那么,吃饭时间长的就先吃 吃饭时间短的就晚点吃 所以, ... 
- 【BZOJ1040】骑士(动态规划)
		[BZOJ1040]骑士(动态规划) 题面 BZOJ 题解 对于每一组厌恶的关系 显然是连边操作 如果是一棵树的话 很显然的树型\(dp\) 但是,现在相当于有很多个基环 也就是在一棵树的基础上再加了 ... 
- 【BZOJ3527】力(FFT)
		[BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ... 
随机推荐
- 6.centos7 gitblit
			1,安装注意事项 1)必须将gitblit安装在/opt/gitblit这个目录下,因为 服务启动的脚本里面默认就是这个路径 如果不按照这个路径安装需要修改脚本 mkdir -p /opt/gitbl ... 
- shiro app
			写在前面 我们知道,shiro框架在Java Web应用中使用时,本质上是通过filter方式集成的. 也就是说,它是遵循过滤器链规则的:filter的执行顺序与在web.xml中定义的顺序一致,如下 ... 
- AppInventor2笔记
			将视觉化的 块语言 翻译为 Android上的实现 的编译器使用了Kawa语言框架,而Kawa是Scheme编程语言的方言,由Per Bothner开发,并由自由软件基金会发布,它是GNU操作系统的一 ... 
- oracle 基础知识(十二)----索引
			一, 索引介绍 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是一个独立于 ... 
- 踩坑--springboot打war包
			springboot需要jdk1.8+tomcat8.0 第一步:从IDEA中通过maven install将项目打成war包 第二步:将war包放在tomcat的webApp目录下,启动tomcat ... 
- (转)shell--read命令的选项及用法
			shell--read命令 原文:https://www.cnblogs.com/lottu/p/3962921.html http://blog.csdn.net/skdkjzz/article/d ... 
- 初探angular
			前言 angular4.0目前已经发布了,angular是mvw框架,所以对其有一个简单的了解还是很有必要的. 目前angular有中文官网,且文档介绍也都是4.x的,但是为了了解其发展过程,我们先了 ... 
- vim代码折叠命令
			1. 折叠方式 可用选项 'foldmethod' 来设定折叠方式:set fdm=*****. 有 6 种方法来选定折叠: manual 手工定义折叠 ind ... 
- POJ 3468——A Simple Problem with Integers——————【线段树区间更新, 区间查询】
			A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 86780 ... 
- Codeforce 609 C—— Load Balancing ——————【想法题】
			C. Load Balancing time limit per test 2 seconds memory limit per test 256 megabytes input standard i ... 
