题目:https://www.luogu.org/problemnew/show/P1312

自己写了很久。又T又WA的。

发现对题理解有误。改完后应该只有T了,但还是T的。

自己写了许多剪枝,很鸡肋。

然后去看Zinn的题解。

重要剪枝:交换的话只从左向右即可!!!向左的只能是空格。两个颜色相同的话就不要换了!(虽然可能需要故意浪费步数?)

然后就变得非常快。但WA了1个点。去掉自以为等价的那个地方就能了,而且好像还变快了?不知为何。该处见注释。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=;
int n,sta[N][],a[N][N][N],cnt,ct[K],sum,mx;
int xx[]={-,,,},yy[]={,-,,};
bool vis[N][N],eflag;
void dfs(int cr,int x,int y,int fx)
{
cnt++;vis[x][y]=;
int tx=x+xx[fx],ty=y+yy[fx];
if(!vis[tx][ty]&&a[cr][tx][ty]==a[cr][x][y])
dfs(cr,tx,ty,fx);
}
void cz(int cr,int x,int y)
{ if(x>&&a[cr][x-][y]==a[cr][x][y]&&a[cr][x-][y]==a[cr][x][y])
dfs(cr,x,y,);
if(y>&&a[cr][x][y-]==a[cr][x][y]&&a[cr][x][y-]==a[cr][x][y])
dfs(cr,x,y,);
//上面两个去掉会错?//去掉上面还会变慢?
if(x<&&a[cr][x+][y]==a[cr][x][y]&&a[cr][x+][y]==a[cr][x][y])
dfs(cr,x,y,);
if(y<&&a[cr][x][y+]==a[cr][x][y]&&a[cr][x][y+]==a[cr][x][y])
dfs(cr,x,y,);
}
void xc(int cr)
{
int tmp[N][N]={};
for(int i=;i<=;i++)
{
int p0=;
for(int j=;j<=;j++)
{
while(p0<&&vis[i][p0])p0++;
if(vis[i][p0]||!a[cr][i][p0])break;
tmp[i][j]=a[cr][i][p0];p0++;
}
}
memcpy(a[cr],tmp,sizeof tmp);
}
void clear(int cr)
{
while()
{
memset(vis,,sizeof vis); cnt=;
for(int i=;i<=;i++)
for(int j=;j<=&&a[cr][i][j];j++)
if(!vis[i][j])cz(cr,i,j);
if(!cnt)break; xc(cr); sum-=cnt;
}
}
void calc(int cr,int x,int y,int op)
{
memcpy(a[cr],a[cr-],sizeof a[cr-]);
if(a[cr][x+op][y])
{
if(a[cr][x][y]==a[cr][x+op][y])return;
swap(a[cr][x][y],a[cr][x+op][y]);
clear(cr); return;
}
else
{
for(int i=;i<=;i++)
if(!a[cr][x+op][i])
{a[cr][x+op][i]=a[cr][x][y];break;}
for(int i=y;i<=;i++)a[cr][x][i]=a[cr][x][i+];
clear(cr); return;
}
}
bool pan(int cr)
{
memset(ct,,sizeof ct);
for(int i=;i<=;i++)
for(int j=;j<=&&a[cr][i][j];j++)
ct[a[cr][i][j]]++;
for(int i=;i<=mx;i++)if(ct[i]==||ct[i]==)return false;
return true;
}
void solve(int cr)
{
if(cr>n)
{
eflag=!sum; return;
}
int ysum=sum;
for(int i=;i<=;i++)
for(int j=;j<=&&a[cr-][i][j];j++)
{
if(i<&&a[cr-][i][j]!=a[cr-][i+][j])
{
calc(cr,i,j,);
if(pan(cr))
{
sta[cr][]=i;sta[cr][]=j;sta[cr][]=;
solve(cr+); if(eflag)return;
}
sum=ysum;
}
if(i>&&!a[cr-][i-][j])
{
calc(cr,i,j,-);
if(pan(cr))
{
sta[cr][]=i;sta[cr][]=j;sta[cr][]=-;
solve(cr+); if(eflag)return;
}
sum=ysum;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=;i++)
for(int j=;j<=;j++)//
{
scanf("%d",&a[][i][j]);
if(!a[][i][j])break;
ct[a[][i][j]]++; sum++; mx=max(mx,a[][i][j]);
}
if(!pan()){puts("-1");return ;} solve();
if(eflag)
{
for(int i=;i<=n;i++)
printf("%d %d %d\n",sta[i][],sta[i][],sta[i][]);
}
else puts("-1");
return ;
}

洛谷 1312 Mayan游戏——暴搜+剪枝的更多相关文章

  1. 洛谷1312 Mayan游戏

    原题链接 讨厌这种大搜索题 基本就是模拟搜索,注意细节即可. 以下是我用的两个剪枝: 将块向左移的前提是左边为空,因为该题要求先右后左,所以若左边有块,那么在上一次搜索向右移的时候一定会搜过,且字典序 ...

  2. 洛谷P2236 HNOI2002 彩票 [暴搜]

    题目传送门 彩票 分析: 虽然题目标签上标的是Splay,但我一个蒟蒻至今也沒掌握平衡树,所以就索性一个暴搜,加一点剪枝就水过去了- 代码: #include<cstdio> #inclu ...

  3. 洛谷P1312 Mayan游戏

    P1312 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他 ...

  4. [NOIP2011] 提高组 洛谷P1312 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  5. 洛谷 P1312 Mayan游戏

    题解:搜索+模拟 剪枝: 最优性剪枝:x从小到大,y从小到大,第一次搜到的就是字典序最小 的最优解. 最优性剪枝:把一个格子和左边格子交换,和左边格子和右边格 子交换是等价的,显然让左边格子和右边交换 ...

  6. 洛古 P1312 Mayan游戏(dfs+剪枝)

    题目链接 这道题和俄罗斯方块很像 很明显,我们可以看出这是一个dfs,但是,我们需要几条剪枝: 1.如果只剩下1个或2个同样颜色的方块,那么直接退出 2.相同的块不用交换 3.注意优先性,优先左边换右 ...

  7. 洛谷 P2197 nim游戏

    洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...

  8. 洛谷 P1965 转圈游戏

    洛谷 P1965 转圈游戏 传送门 思路 每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,--,依此类推,第n − m号位置上的小伙伴走到第 0 号 ...

  9. 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)

    洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...

随机推荐

  1. 使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量

    在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本.在使用Lua的过程中,会常常訪问全局变量来作为配置文件. 在訪问全局变量时,能够通过局部变量引用全局变量来优化. ...

  2. 简单理解 ES7 Decorator(装饰器)

    如何使用ES7 Decorator给你的游戏人物开挂? // 预告: 本文有点小难度,对js不太熟的人可能比较懵逼 // 本文的目的是让你们知其然 // ======================= ...

  3. 开始学习linux的一些疑问

    Linux - Unix环境高级编程(第三版) 代码编译 https://www.linuxidc.com/Linux/2011-08/41228.htm ftp://ftp1.linuxidc.co ...

  4. idea刷新项目、清除项目缓存

    点击File -> Invalidate caches ,点击之后在弹出框中点击确认,之后软件就自动重启了

  5. Linux 下编译安装OpenCV(zhuanzai)

    http://www.cnblogs.com/emouse/archive/2013/02/22/2922940.html Cmake的安装 OpenCV 2.2以后版本需要使用Cmake生成make ...

  6. Linux 系统监控.诊断工具之 IO wait

    1. 常用组合方式有如下几种: 用vmstat.sar.iostat检测是否是CPU瓶颈 用free.vmstat检测是否是内存瓶颈 用iostat.dmesg 检测是否是磁盘I/O瓶颈 用netst ...

  7. idea分支合并

    1.切换到指定分支(例如dev) 2.点击master的merge进行合并 注意:最好删掉本地的master和dev然后重新拉下远程的master和dev生成最新的本地master和dev

  8. java 重定向和转发(转载)

    jsp中result的默认类型为dispatcher. dispatcher:与<jsp:forward page=""/>效果相同 redirect:与respons ...

  9. EasyPlayer实现视频播放局部缩放、广角平移功能(类似水滴直播,快手视频)

    本文转自:http://blog.csdn.net/jyt0551/article/details/56063869 视频播放局部缩放.广角平移功能 在预览图片的时候,利用手势控制图片的缩放.平移,已 ...

  10. Python: lambda, map, reduce, filter

    在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda? 下面就上面的问题进行一下解答. 1.lambda是什么? ...