原题链接

讨厌这种大搜索题

基本就是模拟搜索,注意细节即可。

以下是我用的两个剪枝:

  1. 将块向左移的前提是左边为空,因为该题要求先右后左,所以若左边有块,那么在上一次搜索向右移的时候一定会搜过,且字典序更小。
  2. 对每次搜索的图进行\(HASH\)储存,即记忆化。

表示这题把我\(HASH\)卡了。。最后乱改\(base\),改成\(131\times 1331\)的时候终于过了。。

所以我的代码还是有一定可能性被卡掉的,不过其实只需加第一个剪枝就能通过此题,只不过跑的比较慢(说不定不剪枝也能过,并没有测试过)。

另外,该题还可以加另一个剪枝:若当前状态中有一种块的数量为\(1\)或\(2\),则该状态定无法消去所有块,直接返回。

这里我并没有用该剪枝(感觉并没有必要)。

代码又臭又长

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 10;
const int mod = 999983;
struct cdr {
int x, y, z, p;
cdr()
{
x = y = z = p = 0;
}
};
struct dd {
int x, y, z;
};
dd an[N];
int o[N][N], f[N << 2], v[mod + 10], n, p, ma_co;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline int maxn(int x, int y)
{
return x > y ? x : y;
}
inline void sw(int &x, int &y)
{
int z = x;
x = y;
y = z;
}
int sch_rem(int x, int y, int co, int b[N][N], int l[])
{
int i, s_1 = 1, s_2 = 1;
for (i = y + 1; i <= l[x]; i++)
if (b[x][i] ^ co)
break;
else
s_1++;
for (i = y - 1; i; i--)
if (b[x][i] ^ co)
break;
else
s_1++;
for (i = x + 1; i < 6; i++)
if (b[i][y] ^ co)
break;
else
s_2++;
for (i = x - 1; i; i--)
if (b[i][y] ^ co)
break;
else
s_2++;
if (s_1 > 2 && s_2 > 2)
{
p = 3;
return s_1 + s_2 - 1;
}
if (s_1 > 2)
{
p = 1;
return s_1;
}
if (s_2 > 2)
{
p = 2;
return s_2;
}
return 0;
}
void rem(int x, int y, int hw, int co, int b[N][N], int l[])
{
int i;
b[x][y] = 0;
if (hw ^ 2)
{
for (i = y + 1; i <= l[x]; i++)
if (b[x][i] ^ co)
break;
else
b[x][i] = 0;
for (i = y - 1; i; i--)
if (b[x][i] ^ co)
break;
else
b[x][i] = 0;
}
if (hw ^ 1)
{
for (i = x + 1; i < 6; i++)
if (b[i][y] ^ co)
break;
else
b[i][y] = 0;
for (i = x - 1; i; i--)
if (b[i][y] ^ co)
break;
else
b[i][y] = 0;
}
}
void downbk(int b[N][N], int l[])
{
int i, j, k;
for (i = 1; i < 6; i++)
{
for (j = 1; j <= l[i]; j++)
if (!b[i][j])
break;
for (k = j + 1; k <= l[i]; k++)
if (b[i][k])
break;
if (j <= l[i] && k <= l[i])
for (; k <= l[i]; k++)
{
b[i][j++] = b[i][k];
b[i][k] = 0;
}
l[i] = j - 1;
}
}
int mkhs(int b[N][N])
{
int i, j, k = -1, s = 0;
for (i = 1; i < 6; i++)
for (j = 1; j < 8; j++)
{
k++;
s = (s + 1LL * f[k] * (b[i][j] + 1) % mod) % mod;
}
return s;
}
int try_rem(cdr S[], int b[N][N], int l[])
{
int i, j, s = 0, k;
bool fg = 1;
while (fg)
{
fg = 0;
for (i = 1; i < 6; i++)
for (j = 1; j <= l[i]; j++)
if (S[b[i][j]].z < (k = sch_rem(i, j, b[i][j], b, l)))
{
S[b[i][j]].z = k;
S[b[i][j]].p = p;
S[b[i][j]].x = i;
S[b[i][j]].y = j;
}
for (i = 1; i <= ma_co; i++)
if (S[i].z > 2)
{
rem(S[i].x, S[i].y, S[i].p, i, b, l);
fg = 1;
s += S[i].z;
S[i].z = 0;
}
if (fg)
downbk(b, l);
}
return s;
}
bool dfs(int nw, int la, int a[N][N])
{
int b[N][N], l[N], i, j, k, s;
cdr S[N + 3];
memset(b, 0, sizeof(b));
memset(l, 0, sizeof(l));
for (i = 1; i < 6; i++)
{
for (j = 1; j < 8; j++)
b[i][j] = a[i][j];
l[i] = 7;
}
downbk(b, l);
s = try_rem(S, b, l);
if (nw > n)
{
if (la ^ s)
return false;
return true;
}
for (i = 1; i < 6; i++)
for (j = 1; j <= l[i]; j++)
{
if (i < 5)
{
sw(b[i][j], b[i + 1][j]);
k = mkhs(b);
if (v[k] > nw)
{
v[k] = nw;
if (dfs(nw + 1, la - s, b))
{
an[nw].x = i - 1;
an[nw].y = j - 1;
an[nw].z = 1;
return true;
}
}
sw(b[i][j], b[i + 1][j]);
}
if (i > 1 && !b[i - 1][j])
{
sw(b[i][j], b[i - 1][j]);
k = mkhs(b);
if (v[k] > nw)
{
v[k] = nw;
if (dfs(nw + 1, la - s, b))
{
an[nw].x = i - 1;
an[nw].y = j - 1;
an[nw].z = -1;
return true;
}
}
sw(b[i][j], b[i - 1][j]);
}
}
return false;
}
int main()
{
int i, j, s = 0;
n = re();
memset(v, 60, sizeof(v));
for (f[0] = i = 1; i < 36; i++)
f[i] = 1LL * f[i - 1] * 1331 % mod * 131 % mod;
for (i = 1; i < 6; i++)
for (j = 1; ; j++)
{
o[i][j] = re();
ma_co = maxn(ma_co, o[i][j]);
if (!o[i][j])
{
s += j - 1;
break;
}
}
v[mkhs(o)] = 1;
if (!dfs(1, s, o))
printf("-1");
else
for (i = 1; i <= n; i++)
printf("%d %d %d\n", an[i].x, an[i].y, an[i].z);
return 0;
}

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

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

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

  2. 洛谷P1312 Mayan游戏

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

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

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

  4. 洛谷 P1312 Mayan游戏

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

  5. 洛谷 P2197 nim游戏

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

  6. 洛谷 P1965 转圈游戏

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

  7. 洛谷 P1000 超级玛丽游戏

    P1000 超级玛丽游戏 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级 ...

  8. 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山

    前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...

  9. $loj10156/$洛谷$2016$ 战略游戏 树形$DP$

    洛谷loj Desription Bob 喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的方法.现在他有个问题. 现在他有座古城堡,古城堡的路形成一棵树.他要在这棵树的节点上放置最少数 ...

随机推荐

  1. Oracle11g服务详细介绍

    Oracle11g服务详细介绍及哪些服务是必须开启的? Oracle ORCL VSS Writer Service Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Se ...

  2. canvas画布内部重复画圆

    <!DOCTYPE html><html><head> <title>canvas example</title> <meta cha ...

  3. canvas元素绘制太极图

    <!DOCTYPE html><html><head> <title>canvas example</title> <meta cha ...

  4. Java url爬虫

    java 爬虫抓取 可以在线编辑java代码的连接http://www.runoob.com import java.util.Scanner; import java.util.ArrayList; ...

  5. ssh架构之hibernate(一)简单使用hibernate完成CRUD

    1.Hibernate简介   Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,h ...

  6. springcloud eureka.instance

    1.在springcloud中服务的 Instance ID 默认值是: ${spring.cloud.client.hostname}:${spring.application.name}:${sp ...

  7. Unity入门&物理引擎

    一.Unity六大模块 首先,Unity界面有六大模块,分别是:Hierarchy,Scene,Game,Inspector,Project,Console.下面对这六个视图的功能进行详解. 1.Hi ...

  8. cacti有图无数据解决办法

    Cacti 安装不久,图像界面出来了,但是一直没有数据. Cacti 日志中的错误或警告也都一个个全部解决.有些需要访问文件的权限也都有了. 1.system utilities –>Rebui ...

  9. Mysql 5.7 忘记root密码或重置密码的详细方法

    在Centos中安装完MySQL数据库以后,不知道密码,这可怎么办,下面给大家说一下怎么重置密码 在Centos中安装完MySQL数据库以后,不知道密码,这可怎么办,下面给大家说一下怎么重置密码 1. ...

  10. VM虚拟机 Centos7 lnmp环境 配置域名问题 windows浏览器访问的问题

    CentOS7  ip地址为 192.168.0.155 搭有 LNMP集成环境 执行 lnmp vhost add 配置服务器 指定目录的域名 mark.com 这时windows 机器的 浏览器想 ...