题目链接
http://noi-test.zzstep.com/contest/0x29%E3%80%8C%E6%90%9C%E7%B4%A2%E3%80%8D%E7%BB%83%E4%B9%A0/2903%20Mayan%E6%B8%B8%E6%88%8F
分析
认为 0 0 0 也可以移动,这样每次操作统一,都是一个数水平右移。
若当前局面某数的个数小于 3 3 3,则一定不能成功。
AC代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int maxn = 10, maxc = 15;
struct Ans {
int x, y, z;
} ans[maxn];
int step, map[maxn][maxn], cnt[maxc], order[maxn][maxn];
inline int judge() {
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 7; ++j)
if (map[i][j]) return 0;
return 1;
}
inline void down() {
memset(order, 0, sizeof(order));
for (int i = 1; i <= 5; ++i) {
int p = 0;
for (int j = 1; j <= 7; ++j)
if (map[i][j]) order[i][++p] = map[i][j];
}
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 7; ++j) map[i][j] = order[i][j];
}
inline int del() {
int flag = 0;
for (int i = 1; i <= 3; ++i)
for (int j = 1; j <= 7; ++j) {
if (!map[i][j]) continue;
int t = i;
while (t <= 4 && map[t + 1][j] == map[t][j]) ++t;
if (t - i >= 2) {
flag = 1;
for (int k = i; k <= t; ++k) {
int p = j, q = j;
while (p <= 6 && map[k][p + 1] == map[k][p]) ++p;
while (q >= 2 && map[k][q - 1] == map[k][q]) --q;
if (p - q >= 2) for (int l = q; l <= p; ++l)
map[k][l] = 0;
}
for (int k = i; k <= t; ++k) map[k][j] = 0;
}
}
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 5; ++j) {
if (!map[i][j]) continue;
int t = j;
while (t <= 6 && map[i][t + 1] == map[i][t]) ++t;
if (t - j >= 2) {
flag = 1;
for (int k = j; k <= t; ++k) {
int p = i, q = i;
while (p <= 4 && map[p + 1][k] == map[p][k]) ++p;
while (q >= 2 && map[q - 1][k] == map[q][k]) --q;
if (p - q >= 2) for (int l = q; l <= p; ++l)
map[l][k] = 0;
}
for (int k = j; k <= t; ++k) map[i][k] = 0;
}
}
return flag;
}
void dfs(int done) {
if (done == step) {
if (judge()) {
for (int i = 1; i <= step; ++i)
printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].z);
exit(0);
}
return;
}
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 7; ++j) ++cnt[map[i][j]];
for (int i = 1; i <= 10; ++i)
if (cnt[i] == 1 || cnt[i] == 2) return;
int tmp[maxn][maxn];
memcpy(tmp, map, sizeof(tmp));
for (int i = 1; i <= 4; ++i)
for (int j = 1; j <= 7; ++j) {
if (map[i][j] == map[i + 1][j]) continue;
ans[done + 1].y = j - 1;
if (map[i][j]) ans[done + 1].x = i - 1, ans[done + 1].z = 1;
else ans[done + 1].x = i, ans[done + 1].z = -1;
swap(map[i][j], map[i + 1][j]);
down();
while (del()) down();
dfs(done + 1);
memcpy(map, tmp, sizeof(map));
}
}
int main() {
step = read();
for (int i = 1; i <= 5; ++i) {
int x = read(), j = 0;
while (x) map[i][++j] = x, x = read();
}
dfs(0);
printf("-1");
return 0;
}