题解:搜索+模拟

剪枝:

最优性剪枝:x从小到大,y从小到大,第一次搜到的就是字典序最小

的最优解。

最优性剪枝:把一个格子和左边格子交换,和左边格子和右边格

子交换是等价的,显然让左边格子和右边交换更优。

可行性剪枝:如果当前格子某个颜色个数为1或者2return 一定消不去。

最优性剪枝:相同颜色格子交换并没有什么卵用,当左边是空时和左边交换

几个操作

(1)down()函数 目的是为了让腾空的格子落下

(2)xiao()函数 目的是让三个相同颜色的格子消去

(3)check()函数 当前颜色是否都被消去了

错因:不是蠢是弱呀...,down函数写错了,还有tmp[][]不能设成

全局变量,否则回溯不了....md...orz

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 20
using namespace std;
int n;
int map[maxn][maxn],re[maxn][maxn],ans[maxn][maxn],cnt[maxn]; void read(){
scanf("%d",&n);
for(int i=;i<=;i++){
int nu=,x;
while(){
scanf("%d",&x);
if(!x)break;
map[i][++nu]=x;
}
}
} bool check(){
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(map[i][j])return false;
return true;
} void down(){
for(int i=;i<=;i++){
int nu=,t;
for(int j=;j<=;j++){
// if(map[i][j])map[i][++nu]=map[i][j],map[i][j]=0;
//留住上面沙茶的一行,最后map[][]竟然清0了、
if(map[i][j]){t=map[i][j];map[i][j]=;map[i][++nu]=t;}
}
}
} bool xiao(){
bool flag=false;
memset(re,,sizeof(re));
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(map[i][j]&&map[i][j]==map[i][j-]&&map[i][j]==map[i][j+])
flag=true,re[i][j]=re[i][j-]=re[i][j+]=true;
if(map[i][j]&&map[i][j]==map[i+][j]&&map[i][j]==map[i-][j])
flag=true,re[i][j]=re[i+][j]=re[i-][j]=true;
}
}
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(re[i][j])map[i][j]=;
return flag;
} void dfs(int x){
if(x==n+){
if(check()){
for(int i=;i<=n;i++)
printf("%d %d %d\n",ans[i][]-,ans[i][]-,ans[i][]);
exit();
}
return;
}
int tmp[][];memset(cnt,,sizeof(cnt));
for(int i=;i<=;i++)for(int j=;j<=;j++)tmp[i][j]=map[i][j],cnt[map[i][j]]++;
for(int i=;i<=;i++)if(cnt[i]==||cnt[i]==)return;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(map[i][j]==)break;
if(map[i][j]!=map[i+][j]&&i!=){
swap(map[i][j],map[i+][j]);
ans[x][]=i,ans[x][]=j,ans[x][]=;
down();while(xiao())down();
dfs(x+);
for(int i=;i<=;i++)for(int j=;j<=;j++)map[i][j]=tmp[i][j];
}
if(map[i-][j]==&&i!=){
swap(map[i][j],map[i-][j]);
ans[x][]=i,ans[x][]=j,ans[x][]=-;
down();while(xiao())down();
dfs(x+);
for(int i=;i<=;i++)for(int j=;j<=;j++)map[i][j]=tmp[i][j];
}
}
}
} int main(){
read();dfs();
puts("-1");
return ;
}

AC

20180825

22:02:01

一年后凭借对题解的记忆又写了一遍....比去年好多了...

注意记录答案,如果用flag=1表示找到了答案return,

记录的答案有可能改变。

吸了氧终于过了

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n; int flag; int a[][],ct[]; struct A
{
int x,y,d;
}ans[]; bool ok()
{
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(a[i][j]) return false;
}
}
return true;
} void drop()
{
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
int x=j,y=i;
if(a[j][i]&&(x->=&&!a[x-][y]))
{
while(x->=&&!a[x-][y]) x--;
a[x][y]=a[j][i];
a[j][i]=;
}
}
}
} bool clear()
{
int yes=;
int k[][];
memset(k,,sizeof(k));
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(!a[i][j]) continue;
if(j+<&&j->=&&a[i][j]==a[i][j+]&&a[i][j]==a[i][j-]) yes=,k[i][j]=k[i][j+]=k[i][j-]=;
if(i+<&&i->=&&a[i][j]==a[i+][j]&&a[i][j]==a[i-][j]) yes=,k[i][j]=k[i-][j]=k[i+][j]=;
}
}
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(k[i][j]) a[i][j]=;
}
}
return yes;
} void dfs(int now)
{
int b[][];
if(now==n+&&ok())
{
for(int i=;i<=n;i++) printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
exit();
}
if(now>=n+) return;
memset(ct,,sizeof(ct));
for(int i=;i<;i++) for(int j=;j<;j++) b[i][j]=a[i][j],ct[b[i][j]]++;
for(int i=;i<=;i++) if(ct[i]&&ct[i]<) return ;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(!a[j][i]) continue;
if(a[j][i]!=a[j][i+]&&i+<)
{
swap(a[j][i],a[j][i+]);
drop(); while(clear()) drop();
ans[now].x=i;ans[now].y=j;ans[now].d=;
dfs(now+);
for(int c=;c<;c++) for(int d=;d<;d++) a[c][d]=b[c][d];
}
if(i->=&&a[j][i]!=a[j][i-])
{
swap(a[j][i],a[j][i-]);
drop();while(clear()) drop();
ans[now].x=i;ans[now].y=j;ans[now].d=-;
dfs(now+);
for(int c=;c<;c++) for(int d=;d<;d++) a[c][d]=b[c][d];
}
}
}
} int main()
{
scanf("%d",&n);
for(int i=;i<;i++)
{
int cnt=,x;
while()
{
scanf("%d",&x);
if(!x) break;
a[cnt++][i]=x;
}
}
dfs();
printf("-1\n");
return ;
}

AC

洛谷 P1312 Mayan游戏的更多相关文章

  1. 洛谷P1312 Mayan游戏

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

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

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

  3. 洛谷 1312 Mayan游戏——暴搜+剪枝

    题目:https://www.luogu.org/problemnew/show/P1312 自己写了很久.又T又WA的. 发现对题理解有误.改完后应该只有T了,但还是T的. 自己写了许多剪枝,很鸡肋 ...

  4. 洛谷1312 Mayan游戏

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

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

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

  6. 洛谷 P2197 nim游戏

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

  7. 洛谷 P1965 转圈游戏

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

  8. Luogu P1312 Mayan游戏(搜索)

    P1312 Mayan游戏 题意 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个\(7\)行\(\times 5\)列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必 ...

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

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

随机推荐

  1. 分布式集群Session原理及实现共享

    1.什么是Session/Cookie? 用户使用网站的服务,基本上需要浏览器与Web服务器的多次交互.HTTP协议本身是无状态的,当用户的第一次访问请求结束后,后端服务器就无法知道下一次来访问的还是 ...

  2. 从零开始玩转logback

    概述 LogBack是一个日志框架,它与Log4j可以说是同出一源,都出自Ceki Gülcü之手.(log4j的原型是早前由Ceki Gülcü贡献给Apache基金会的)下载地址:http://l ...

  3. 如何在MyEclipse中更改servlet模板 Jsp模板

    http://blog.csdn.net/sjw890821sjw/article/details/6995190 刚换上Myeclipse9.0,结果要修改servlet模板的时候不像Myeclps ...

  4. Search for a range, 在一个可能有重复元素的有序序列里找到指定元素的起始和结束位置

    问题描述:给定一个有序序列,找到指定元素的起始和结束位置.例如:1234555,5,起始4结束6 算法分析:其实就是一个二分查找的利用.但是特殊就在不是找到某个元素,而是找到下标.也就是在nums[m ...

  5. 一块网卡多个IP实现

    ////////////////////////////写在前面//////////////////////////////////////////// 需要注意,这里我们是一块网卡多个IP,而并非是 ...

  6. 使用mybatis如果类属性名和数据库中的属性名不一样取值就会为null

    使用mybatis时如果类属性名和数据库中的属性名不一样取值就会为null 这是不能再去改变javabean中的属性,只能改变sql语句.语句如下所示: <select id="sel ...

  7. 关于jQuery中的offset()和position()

    在jQuery中有两个获取元素位置的方法offset()和position().position()方法是在1.2.6版本之后加入的,为什么要引 入这个方法呢?这两个方法之间有什么异同?使用的时候应该 ...

  8. 51nod-1526-贪心+Trie

    题目链接在这 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 班里有n个同学.老师为他们选了n个笔名.现在要把这些笔 ...

  9. NPOI将xls文件解析为DataTable类数据

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  10. 【2018年全国多校算法寒假训练营练习比赛(第五场)-C】字符串问题(KMP)

    题目链接:https://www.nowcoder.com/acm/contest/77/C [题意] 求一个字符串中最长的子串,要求子串既是原串的前缀又是后缀,除前后缀还在中间出现过. [思路] K ...