⌈洛谷1312⌋⌈NOIP提高组2011⌋Mayan游戏【搜索】

时间:2022-08-25 00:03:49

感想

真的,感觉这道题目好坑爹,我这个蒟蒻调了好几个世纪才调出来。
重构代码千万遍,依旧只有-1输出。

正解

非常明显的一道搜索题目。
每一次记录上一级的状态,这样实现比较不容易出错。
然后考虑剪枝:如果相同就不交换。
以下这个代码开了O2才过掉。

代码

#include <bits/stdc++.h>
#define ms(a, b) memset(a, b, sizeof(a))
#define ll long long
#define ull unsigned long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define db double
#define Pi acos(-1)
#define eps 1e-8
#define N 15
using namespace std;
template <typename T> T sqr(T x) { return x * x; }
template <typename T> void read(T &x) {
    x = 0; T fl = 1; char ch = 0;
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    x *= fl;
}
template <typename T> T power(T x, T y, T mod) { T res = 1;  for (; y; y >>= 1) { if (y & 1) res = (res * x) % mod; x = (x * x) % mod; } return res; }
template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); }
template <typename T> void writeln(T x) { write(x); puts(""); }
struct Ans_Rec{ int x, y, opt; } ans[N];
int a[N][N][N], tmp[N][N];
int n;
bool Is_Empty(int d) { for (int i = 0; i < 5; i ++) for (int j = 0; j < 7; j ++) if (a[d][i][j]) return false; return true; }
void Fall_Down(int d) {
    for (int i = 0; i < 5; i ++)  {
        int sz = 0; for (int j = 0; j < 7; j ++) if (a[d][i][j]) a[d][i][sz ++] = a[d][i][j];
        while (sz < 7) a[d][i][sz ++] = 0;
    }
}
void print() { for (int i = 1; i <= n; i ++) printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].opt); }
void upd(int d) {
    for (bool flag = true; flag; ) {
        flag = false;
        Fall_Down(d);
        for (int i = 0; i < 5; i ++) for (int j = 0; j < 7; j ++) if (a[d][i][j]) {
            if (i < 3) if (a[d][i][j] == a[d][i + 1][j] && a[d][i][j] == a[d][i + 2][j]) flag = tmp[i][j] = tmp[i + 1][j] = tmp[i + 2][j] = 1;
            if (j < 5) if (a[d][i][j] == a[d][i][j + 1] && a[d][i][j] == a[d][i][j + 2]) flag = tmp[i][j] = tmp[i][j + 1] = tmp[i][j + 2] = 1;
        }
        for (int i = 0; i < 5; i ++) for (int j = 0; j < 7; j ++) if (tmp[i][j]) a[d][i][j] = tmp[i][j] = 0;
    }
}
void dfs(int Orz) {
    for (int i = 0; i < 5; i ++) for (int j = 0; j < 7; j ++) a[Orz][i][j] = a[Orz - 1][i][j];
    upd(Orz);
    if (Orz == n + 1) { if (Is_Empty(Orz)) {print(); exit(0); } return; }
    for (int i = 0; i < 5; i ++) for (int j = 0; j < 7; j ++) if (a[Orz][i][j]) {
        if (i < 4 && a[Orz][i][j] != a[Orz][i + 1][j]) {
            ans[Orz].x = i, ans[Orz].y = j, ans[Orz].opt = 1;
            swap(a[Orz][i][j], a[Orz][i + 1][j]);
            dfs(Orz + 1);
            swap(a[Orz][i][j], a[Orz][i + 1][j]);
        }
        if (i && a[Orz][i][j] != a[Orz][i - 1][j]) {
            ans[Orz].x = i, ans[Orz].y = j, ans[Orz].opt = -1;
            swap(a[Orz][i][j], a[Orz][i - 1][j]);
            dfs(Orz + 1);
            swap(a[Orz][i][j], a[Orz][i - 1][j]);
        }
    }
}
int main() {
    read(n);
    for (int i = 0; i < 5; i ++) { for (int j = 0; ; j ++) { read(a[0][i][j]); if (a[0][i][j] == 0) break; }}
    dfs(1); puts("-1");
    return 0;
}