洛谷1312 Mayan游戏
原题链接
讨厌这种大搜索题
基本就是模拟搜索,注意细节即可。
以下是我用的两个剪枝:
- 将块向左移的前提是左边为空,因为该题要求先右后左,所以若左边有块,那么在上一次搜索向右移的时候一定会搜过,且字典序更小。
- 对每次搜索的图进行\(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游戏的更多相关文章
- 洛谷 1312 Mayan游戏——暴搜+剪枝
题目:https://www.luogu.org/problemnew/show/P1312 自己写了很久.又T又WA的. 发现对题理解有误.改完后应该只有T了,但还是T的. 自己写了许多剪枝,很鸡肋 ...
- 洛谷P1312 Mayan游戏
P1312 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他 ...
- [NOIP2011] 提高组 洛谷P1312 Mayan游戏
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- 洛谷 P1312 Mayan游戏
题解:搜索+模拟 剪枝: 最优性剪枝:x从小到大,y从小到大,第一次搜到的就是字典序最小 的最优解. 最优性剪枝:把一个格子和左边格子交换,和左边格子和右边格 子交换是等价的,显然让左边格子和右边交换 ...
- 洛谷 P2197 nim游戏
洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...
- 洛谷 P1965 转圈游戏
洛谷 P1965 转圈游戏 传送门 思路 每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,--,依此类推,第n − m号位置上的小伙伴走到第 0 号 ...
- 洛谷 P1000 超级玛丽游戏
P1000 超级玛丽游戏 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级 ...
- 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山
前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...
- $loj10156/$洛谷$2016$ 战略游戏 树形$DP$
洛谷loj Desription Bob 喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的方法.现在他有个问题. 现在他有座古城堡,古城堡的路形成一棵树.他要在这棵树的节点上放置最少数 ...
随机推荐
- Numpy知识(一)
先了解ndarray(一个多维数组)的生成. 第一种生成方法就是np.random.randn(n,m),这回生成一个形状是n*m的ndarray.如下图. 第二种生成方法:传入一个列表listDem ...
- slot 插槽的使用
在vue 中父组件中的子组件在子组件中添加内容(html标签.文本内容),在子组件中加入slot这样页面中就会呈现出在父组件填写的内容,例如: 父组件中hello是子组件,在子组件中插入slot这样子 ...
- php挖掘数据编码问题
if(json_encode($jkkey) == 'null'){//判断不是utf8会返回空 $jkkey=mb_convert_encoding($jkkey,'utf-8','gbk'); } ...
- Light Explorer
[Light Explorer] The Light Explorer allows you to select and edit light sources. Window> Lighting ...
- MySQL driver for Node
[MySQL driver for Node] 1.安装 2.一个示例 From this example, you can learn the following: Every method you ...
- 如何使用eclipse创建JAVA项目并写一个简单的HelloWorld
输入项目名称 点击完成(Finish) 原文地址:https://blog.csdn.net/qq_36798713/article/details/79530056
- 第十章 优先级队列 (a2)基本实现
- c++ - Linking problems due to symbols with abi::cxx11?
看错误内容: /data/projects/LipReadingSDKGPU/lib/cwlibs/libLipReading.so: undefined reference to `tensorfl ...
- CentOS 下搭建Hudson
1.下载Hudson安装包 wget http://ftp.jaist.ac.jp/pub/eclipse/hudson/war/hudson-3.3.3.war 2.执行 java -jar hud ...
- 202. Happy Number (INT)
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...