Luogu P4205 [NOI2005]智慧珠游戏
国内少有的可以练习神仙算法——DLX的好题怎么可以被爆搜埋没呢?
看到这题没有DLX的题解所以写一篇,不过貌似我实现的太弱(构图太慢)所以速度上不是很快。
下面开始讲题,但请保证你要先学会DLX。(dalao写的超详细DLX)
首先仔细阅读一遍题目,我们可以大致整理出题意:用\(12\)块拼图填满一个\(10\)行的三角形图案
稍微分析下性质发现我们其实只要满足:每个位置都有拼图和每种拼图都出现了\(1\)次即可。
所以类似于数独我们可以把它转化为一个精确覆盖问题:
行表示任意一种颜色的珠子不同放置(任意一个位置不同都算作不同)
有\(55+12=67\)列。前\(55\)列表示每一个位置都要有珠子,后\(12\)列要求每种颜色的珠子都要有。
考虑建图,由于数据范围实在很小,我们可以直接暴力搞。
对于每一种颜色,先手动打表求出每一个珠子关于一个珠子的相对坐标差值。
然后直接枚举位置?但是这样并没有包括旋转和翻转的情况,难道还要打一个\(8\)倍的表?
没必要,我们可以直接枚举坐标优先加到横坐标还是纵坐标,同时枚举一下每次的正负号即可(这个具体看代码吧,很好理解的)
所以这个问题就被我们转化为了一个\(2730\)行,\(67\)列,\(1\)的个数为\(15084\)的精确覆盖问题了。直接上DLX即可。
值得一提的是作为正解的DLX码量远远小于爆搜。(我写了加上注释\(106\)行,而且大括号都换行了)
CODE
#include<cstdio>
#include<cstring>
#define RI register int
#define CI const int&
#define Ms(f,x) memset(f,x,sizeof(f))
using namespace std;
const int N=15,multag[2]={-1,1};
const int length[12]={3,4,4,4,5,5,5,5,5,5,5,5}; //length of shapes
const int table[12][5][2]= //direction of shapes
{
{{0,0},{1,0},{0,1}}, //A
{{0,0},{0,1},{0,2},{0,3}}, //B
{{0,0},{1,0},{0,1},{0,2}}, //C
{{0,0},{1,0},{0,1},{1,1}}, //D
{{0,0},{1,0},{2,0},{2,1},{2,2}}, //E
{{0,0},{0,1},{1,1},{0,2},{0,3}}, //F
{{0,0},{1,0},{0,1},{0,2},{1,2}}, //G
{{0,0},{1,0},{0,1},{1,1},{0,2}}, //H
{{0,0},{0,1},{0,2},{1,2},{1,3}}, //I
{{0,0},{-1,1},{0,1},{1,1},{0,2}}, //J
{{0,0},{1,0},{1,1},{2,1},{2,2}}, //K
{{0,0},{1,0},{0,1},{0,2},{0,3}}, //L
};
const int numx[56]={0,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10};
const int numy[56]={0,1,1,2,1,2,3,1,2,3,4,1,2,3,4,5,1,2,3,4,5,6,1,2,3,4,5,6,7,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10};
int tx[2],nx[2],num[N][N],id[2750],numrow,numcol; char puzzle[N][N]; bool vis[N];
class Dancing_Links_AlgorithmX
{
private:
static const int N=2750,M=80,ALL=15100;
int n,m,tot,L[ALL],R[ALL],U[ALL],D[ALL],Row[ALL],Col[ALL],H[N],S[M];
#define Dance(i,A,s) for (i=A[s];i!=s;i=A[i])
inline void remove(CI c)
{
L[R[c]]=L[c]; R[L[c]]=R[c]; RI i,j;
Dance(i,D,c) Dance(j,R,i)
U[D[j]]=U[j],D[U[j]]=D[j],--S[Col[j]];
}
inline void resume(CI c)
{
RI i,j; Dance(i,U,c) Dance(j,L,i)
++S[Col[U[D[j]]=D[U[j]]=j]];
L[R[c]]=R[L[c]]=c;
}
public:
inline void init(CI N,CI M)
{
n=N; m=M; for (RI i=0;i<=m;++i)
S[i]=0,U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
R[m]=0; L[0]=m; tot=m; Ms(H,0);
}
inline void link(CI r,CI c)
{
++S[Col[++tot]=c]; Row[tot]=r;
D[tot]=D[c]; U[D[c]]=tot; U[tot]=c; D[c]=tot;
if (!H[r]) H[r]=L[tot]=R[tot]=tot; else
R[tot]=R[H[r]],L[R[H[r]]]=tot,L[tot]=H[r],R[H[r]]=tot;
}
inline bool DFS(void)
{
if (!R[0]) return 1; RI i,j; int now=R[0];
Dance(i,R,0) if (S[i]<S[now]) now=i;
remove(now); Dance(i,D,now)
{
if (Col[i]<=55) puzzle[numx[Col[i]]][numy[Col[i]]]=id[Row[i]]+'A';
Dance(j,R,i) remove(Col[j]),(Col[j]<=55)&&(puzzle[numx[Col[j]]][numy[Col[j]]]=id[Row[j]]+'A');
if (DFS()) return 1; Dance(j,L,i) resume(Col[j]);
}
resume(now); return 0;
}
#undef Dance
}DLX;
inline void init(void)
{
RI i,j; for (i=1;i<=10;++i) for (j=1;j<=i;++j) if (puzzle[i][j]!='.') vis[puzzle[i][j]-'A']=1;
for (i=1;i<=10;++i) for (j=1;j<=i;++j) num[i][j]=++numcol; DLX.init(2730,numcol+12);
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (i=1;i<=10;++i) scanf("%s",puzzle[i]+1);
//build excat cover model
init(); for (RI cases=0,mx;cases<12;++cases)
for (++numcol,mx=0;mx<2;++mx) for (RI dx=0;dx<2;++dx) for (RI dy=0;dy<2;++dy)
for (tx[0]=1;tx[0]<=10;++tx[0]) for (tx[1]=1;tx[1]<=tx[0];++tx[1])
{
RI k; bool flag=1; for (k=0;k<length[cases];++k)
{
nx[mx]=tx[mx]+multag[dx]*table[cases][k][0];
nx[mx^1]=tx[mx^1]+multag[dy]*table[cases][k][1];
if (vis[cases]) { if (puzzle[nx[0]][nx[1]]!=cases+'A') { flag=0; break; } }
else if (puzzle[nx[0]][nx[1]]!='.') { flag=0; break; }
}
if (!flag) continue; id[++numrow]=cases; DLX.link(numrow,numcol);
for (k=0;k<length[cases];++k)
{
nx[mx]=tx[mx]+multag[dx]*table[cases][k][0];
nx[mx^1]=tx[mx^1]+multag[dy]*table[cases][k][1];
DLX.link(numrow,num[nx[0]][nx[1]]);
}
}
//use Dancing Links to find solution
if (!DLX.DFS()) return puts("No solution"),0;
for (i=1;i<=10;++i,putchar('\n')) for (RI j=1;j<=i;++j)
putchar(puzzle[i][j]); return 0;
}
Luogu P4205 [NOI2005]智慧珠游戏的更多相关文章
- 洛谷 P4205 [NOI2005]智慧珠游戏 DFS
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P4205 [NOI2005]智慧珠游戏 题目描述 智慧 ...
- bzoj 1501: [NOI2005]智慧珠游戏 Dancing Link
1501: [NOI2005]智慧珠游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 190 Solved: 122[Submit][Status] ...
- 【搜索好题】bzoj1501 [NOI2005]智慧珠游戏
bzoj1501 [NOI2005]智慧珠游戏 搜索苟逼题系列. 暴力枚举每一种情况(包括旋转翻转全都考虑在内)然后码出代码. (正解似乎不是这样子的) 那年好像还有平衡树苟逼题维护数列233333心 ...
- [BZOJ1501][NOI2005] 智慧珠游戏
Input 文件中包含初始的盘件描述,一共有10行,第i行有i个字符.如果第i行的第j个字符是字母”A”至”L”中的一个,则表示第i行第j列的格子上已经放了零件,零件的编号为对应的字母.如果第i行的第 ...
- 【BZOJ1501】【NOI2005】智慧珠游戏(搜索)
[BZOJ1501][NOI2005]智慧珠游戏(搜索) 题面 我要一改我懒惰的作风 这道题目必须放题面 Description Input 文件中包含初始的盘件描述,一共有10行,第i行有i个字符. ...
- BZOJ 1501 智慧珠游戏
Description Input 文件中包含初始的盘件描述,一共有10行,第i行有i个字符.如果第i行的第j个字符是字母”A”至”L”中的一个,则表示第i行第j列的格子上已经放了零件,零件的编号为对 ...
- ios版弹珠游戏源码
这个是我们比较喜欢玩的一直小游戏的,ios版弹珠游戏源码,该游戏源码来着IOS教程网其他网友提供上传的,大家可以了解一下吧. nore_js_op> <ignore_js_op&g ...
- luogu P2254 [NOI2005]瑰丽华尔兹
题目链接 luogu P2254 [NOI2005]瑰丽华尔兹 题解 为什么我我我不放放放bzoj的链接呢? 因为打的暴力啊,然后bzojT了呀QAQQQQQ(逃 然后luogu竟然过了呀呀呀 dp[ ...
- zzulioj--1790-- 弹珠游戏(数学水题!)
弹珠游戏 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 14 Solved: 10 SubmitStatusWeb Board Descriptio ...
随机推荐
- Elasticsearch Query DSL
Elasticsearch Query DSL By:授客 QQ:1033553122 1. match_all 1 2. match 2 3. match_phrase 5 4. match_phr ...
- Python高级特性:迭代
迭代的目的是实现遍历出一个可迭代对象的元素,即for循环 基本语法 : for ... in ... 首先只有可迭代对象才可以迭代,判断一个对象是不是可以迭代的方法如下: >>> f ...
- python 饥饿的小易(网易笔试题)
本周早些时候,学弟给我发了一道网易的笔试题,饥饿的小易,感觉有点意思-分享给大家 题目描述: 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前 ...
- 【JS基础】类型转换——不同数据类型比较
小试牛刀 输出下列数据比较结果 [] == 0; //==============================================================true [] == ...
- java笔记----线程状态转换函数
注意:stop().suspend()和 resume()方法现在已经不提倡使用,这些方法在虚拟机中可能引起“死锁”现象.suspend()和 resume()方法的替代方法是 wait()和 sle ...
- 洗礼灵魂,修炼python(91)-- 知识拾遗篇 —— pymysql模块之python操作mysql增删改查
首先你得学会基本的mysql操作语句:mysql学习 其次,python要想操作mysql,靠python的内置模块是不行的,而如果通过os模块调用cmd命令虽然原理上是可以的,但是还是不太方便,那么 ...
- Incorrect key file for table错误解决方法
问题现象: alter table portal_app_xxxx_xxx add devno varchar(64) NOT NULL DEFAULT '' COMMENT '设备机编',add s ...
- c/c++ 多态的实现原理分析
多态的实现原理分析 当类里有一个函数被声明成虚函数后,创建这个类的对象的时候,就会自动加入一个__vfptr的指针, __vfptr维护虚函数列表.如果有三个虚函数,则__vfptr指向的是第一个虚函 ...
- Unity Shader 基础(2) Image Effect
Unity中 Image Effect 是Post Processing的一种方,Unity自身也提供很多Effect效果供使用.Image Effect的使用官方文档做了很多介绍,这里重点Post ...
- Unity Shader 基础(3) 获取深度纹理
Unity提供了很多Image Effect效果,包含Global Fog.DOF.Boom.Blur.Edge Detection等等,这些效果里面都会使用到摄像机深度或者根据深度还原世界坐标实现各 ...