题目: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. SPFA 求带负权的单源最短路

    int spfa_bfs(int s) { ///s表示起点. queue <int> q; memset(d,0x3f,sizeof(d)); ///d数组中存下的就是最短路径(存在的话 ...

  2. python_获得列表中重复的项的索引

    a = ['b','a', 'b', 'c', 'a', 'c','d'] b=[] f=[] for i in a: c=[] for item in enumerate(a): if item[1 ...

  3. C 标准库 - <limits.h>

    C 标准库 - <limits.h> 简介 limits.h 头文件决定了各种变量类型的各种属性.定义在该头文件中的宏限制了各种变量类型(比如 char.int 和 long)的值. 这些 ...

  4. Java如何Attachment源码

    该文章教你如何在Eclipse中Attachment源码,学到了不少东西. http://jingyan.baidu.com/article/1709ad80b107f64635c4f040.html ...

  5. ListView中button监听器 设置 及 优化

    在应用开发中常常会用到ListView,而且每个Item里面都会有button之类的须要进行事件监听的控件.在给button加入OnClickListener的时候,一開始非常下意识的会想在ListV ...

  6. 如何获得(读取)web.xml配置文件的參数

    參考代码例如以下: com.atguigu.struts2.app.converters.DateConverter.java public DateFormat getDateFormat(){ i ...

  7. 算法排序-lowB三人组

    冒泡排序思路: 选择排序思路: 插入排序思路: 小结: 详细代码解释看下一篇

  8. FALSE_IT

    本文讲一个实用的语法糖(suger),很不错,攻克了我实际工作中的问题. 如果你写了这样一个类: class Executor { int step1(); void step2(); int ste ...

  9. Model Vaildation

    https://docs.asp.net/en/latest/mvc/models/validation.html 许多有用的验证属性都必须引用命名空间: System.ComponentModel. ...

  10. sql server t-sql脚本转成oracle plsql

    将一份SQL SERVER数据库生成的T-SQL脚本,转成ORACLE的PL/SQL,其复杂繁琐程度,远远出乎我的意料. 这份SQL SERVER脚本,里面有表,有视图,还有存储过程,以及一些自定义函 ...