NOIP 2011 Day1 Problem3

来源:互联网 发布:5230手机加密软件 编辑:程序博客网 时间:2024/05/22 13:47

谢谢 Vfleaking 的大力支持!

#include <iostream>#include <cstdio>#include <cstring>#include <functional>#include <algorithm>using namespace std;const int N = 7, M = 5;const int MaxDepth = 5;int a[N][M];int depth;bool successed = false;struct step{    int x, y, fx;        inline step(){}    inline step(int mx, int my, int mfx) : x(mx), y(my), fx(mfx){}};step res[MaxDepth];inline void input(){    cin >> depth;    for (int i = 0; i < M; i++)        for (int j = 0, t; cin >> t, t != 0; a[j][i] = t, j++);}bool b[N][M];inline bool missing(){    memset(b, 0, sizeof(b));        for (int i = 0; i < N; i++)        for (int j = 1, sum = 1; j <= M; j++)            if (j == M || a[i][j] != a[i][j - 1])            {                if (sum >= 3)                    for (int k = 1; k <= sum; k++)                        b[i][j - k] = true;                sum = 1;            }            else                sum++;    for (int i = 0; i < M; i++)        for (int j = 1, sum = 1; j <= N && a[j - 1][i] != 0; j++)            if (j == N || a[j][i] == 0 || a[j][i] != a[j - 1][i])            {                if (sum >= 3)                    for (int k = 1; k <= sum; k++)                        b[j - k][i] = true;                sum = 1;            }            else                sum++;    bool res = false;    for (int i = 0; i < M; i++)    {        for (int j = 0, k = 0; j < N && a[j][i] != 0; j++)        {            if (!b[j][i])                a[j - k][i] = a[j][i];            else            {                k++;                res = true;            }            if (k != 0)                a[j][i] = 0;        }    }        return res;}inline bool move(int x, int y, int fx){    if (x + fx < 0 || x + fx >= M)        return false;        if (a[y][x + fx] != 0)    {        if (fx == -1)            return false;        swap(a[y][x + fx], a[y][x]);    }    else    {        a[y][x + fx] = a[y][x];        a[y][x] = 0;                for (int i = y; i != 0 && a[i - 1][x + fx] == 0; i--)            a[i - 1][x + fx] = a[i][x + fx], a[i][x + fx] = 0;        for (int i = y + 1; i < N && a[i][x] != 0; i++)            a[i - 1][x] = a[i][x], a[i][x] = 0;    }        while (missing());        return true;}inline bool empty(){    for (int i = 0; i < M; i++)        if (a[0][i] != 0)            return false;    return true;}int backup[MaxDepth][N][M];void dfs(int d){    memmove(backup[d], a, sizeof(a));    for (int i = 0; i < M; i++)        for (int j = 0; a[j][i] != 0 && j < N; j++)        {            if (move(i, j, 1))            {                res[d] = step(i, j, 1);                if (d + 1 == depth)                {                    if (empty())                    {                        successed = true;                        return;                    }                }                else                {                    dfs(d + 1);                    if (successed)                        return;                }                memmove(a, backup[d], sizeof(a));            }                        if (move(i, j, -1))            {                res[d] = step(i, j, -1);                if (d + 1 == depth)                {                    if (empty())                    {                        successed = true;                        return;                    }                }                else                {                    dfs(d + 1);                    if (successed)                        return;                }                memmove(a, backup[d], sizeof(a));            }        }}int main(){    freopen("mayan.in", "r", stdin);    freopen("mayan.out", "w", stdout);        input();        dfs(0);        if (successed)        for (int i = 0; i < depth; i++)            cout << res[i].x << " " << res[i].y << " " << res[i].fx << endl;    else        cout << "-1" << endl;        return 0;}