原题链接

讨厌这种大搜索题

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

以下是我用的两个剪枝:

  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. java 代理学习

    转自黄勇大神的博客.http://my.oschina.net/huangyong/blog/159788 Proxy,也就是“代理”了.意思就是,你不用去做,别人代替你去处理. 它在程序开发中起到了 ...

  2. 百度地图报错:APP Referer校验失败

    今天微信小程序,通过经纬度,调用百度api,将经纬度转换成城市名和街道地址,结果小程序报错. 错误信息如下: 这个是KEY的白名单设置问题.因为白名单设置限制了来源信息.只要在下面红色部分设置IP,或 ...

  3. 通过GCEASY 和 jfr 发现运行时问题

    进入 /dev/shm  目录 ,gc-xxx-xx  的gc 文件 ,上次 gceasy  进行分析 另外 ,通过打开 飞行记录器  , 打开jmc  通过jmx  端口连接上去 ,并启用飞行记录器 ...

  4. java-学习1

    作为一个想要深入的程序猿,只是学习前端是不够的,我总结我的前端工作是围绕着html.css.js展开写的再好也是展现在表面,所以 我想学习一门能够深入的后台语言,想来想去我还是选择java作为以后深入 ...

  5. float double

    float : 单精度浮点数 double : 双精度浮点数 两者的主要区别如下: 01.在内存中占有的字节数不同 单精度浮点数在机内存占4个字节 双精度浮点数在机内存占8个字节 02.有效数字位数不 ...

  6. SpringBoot @Async注解失效分析

    有时候在使用的过程中@Async注解会失效(原因和@Transactional注解有时候会失效的原因一样). 下面定义一个Service: 两个异步执行的方法test03()和test02()用来模拟 ...

  7. Spring集成MyBatis的使用-使用SqlSessionTemplate

    Spring集成MyBatis的使用 Spring集成MyBatis,早期是使用SqlSessionTemplate,当时并没有用Mapper映射器,既然是早期,当然跟使用Mapper映射器是存在一些 ...

  8. Loading AssetBundle Manifests

    [Loading AssetBundle Manifests] AssetBundle Manifest 可以用于获取dependency. AssetBundle assetBundle = Ass ...

  9. MySql union与order by

    [MySql union与order by] 如果您想使用ORDER BY或LIMIT子句来对全部UNION结果进行分类或限制,则应对单个地SELECT语句加圆括号,并把ORDER BY或LIMIT放 ...

  10. SQLMAP自动注入(二)

    --data 添加post头 --data 添加get头 --cookie 添加cookie 设置探测级别大于等于2时会探测cookie是否有注入点 --random-agent 随机生成user-a ...