SPOJ TETRIS2D - Exciting Time

Posted ichneumon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ TETRIS2D - Exciting Time相关的知识,希望对你有一定的参考价值。

数据结构homework出这种题简直丧心病狂好吧。。

注意题意没说请的下落其实就是消去一行的上面所有点高度统一减小1,于是会有悬空的情况出现——怕是假的俄罗斯方块= =

做法就是每列维护一个链表,里面的节点表示一个方块,同一行的方块同时连向一个表示行高的头节点。

插入一个新方块就在每个链表的尾部操作一番,利用相对位置就可以在行链表里面爬;一行满了就消去一行,在每个链表中删即可。

#include <climits>
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

char gchar() {
    char r = getchar();
    while (r ==   || r == \n || r == \r)
        r = getchar();
    return r;
}

int id(char t) {
    switch (t) {
        case I:
            return 0;
        case J:
            return 1;
        case L:
            return 2;
        case O:
            return 3;
        case S:
            return 4;
        case T:
            return 5;
        case Z:
            return 6;
    }
    while (1);
    assert(false);
    return -1;
}
int getScore(int t) {
    switch (t) {
        case 1:
            return 100;
        case 2:
            return 250;
        case 3:
            return 400;
        case 4:
            return 1000;
    }
    while (1);
    assert(false);
    return -1;
}

int tile[][4][4][2] = {
    {
        {
            {0, 0}, {0, 1}, {0, 2}, {0, 3}
        },
        {
            {0, 0}, {1, 0}, {2, 0}, {3, 0}
        },
        {
            {0, 0}, {0, 1}, {0, 2}, {0, 3}
        },
        {
            {0, 0}, {1, 0}, {2, 0}, {3, 0}
        }
    },
    {
        {
            {0, 0}, {0, 1}, {0, 2}, {1, 0}
        },
        {
            {0, 0}, {1, 0}, {2, 0}, {2, 1}
        },
        {
            {-1, 2}, {0, 0}, {0, 1}, {0, 2}
        },
        {
            {0, 0}, {0, 1}, {1, 1}, {2, 1}
        }
    },
    {
        {
            {0, 0}, {0, 1}, {0, 2}, {1, 2}
        },
        {
            {0, 0}, {0, 1}, {1, 0}, {2, 0}
        },
        {
            {0, 0}, {1, 0}, {1, 1}, {1, 2}
        },
        {
            {0, 0}, {-2, 1}, {-1, 1}, {0, 1}
        }
    },
    {
        {
            {0, 0}, {0, 1}, {1, 0}, {1, 1}
        },
        {
            {0, 0}, {0, 1}, {1, 0}, {1, 1}
        },
        {
            {0, 0}, {0, 1}, {1, 0}, {1, 1}
        },
        {
            {0, 0}, {0, 1}, {1, 0}, {1, 1}
        }
    },
    {
        {
            {0, 0}, {0, 1}, {1, 1}, {1, 2}
        },
        {
            {0, 0}, {1, 0}, {-1, 1}, {0, 1}
        },
        {
            {0, 0}, {0, 1}, {1, 1}, {1, 2}
        },
        {
            {0, 0}, {1, 0}, {-1, 1}, {0, 1}
        }
    },
    {
        {
            {0, 0}, {0, 1}, {0, 2}, {1, 1}
        },
        {
            {0, 0}, {1, 0}, {2, 0}, {1, 1}
        },
        {
            {0, 0}, {-1, 1}, {0, 1}, {0, 2}
        },
        {
            {0, 0}, {-1, 1}, {0, 1}, {1, 1}
        }
    },
    {
        {
            {0, 0}, {-1, 1}, {0, 1}, {-1, 2}
        },
        {
            {0, 0}, {1, 0}, {1, 1}, {2, 1}
        },
        {
            {0, 0}, {-1, 1}, {0, 1}, {-1, 2}
        },
        {
            {0, 0}, {1, 0}, {1, 1}, {2, 1}
        },
    },
};

const int N = 3e5 + 100;
int w, n;
struct Node;
struct Row:vector<Node*> {
    int h;
    Row *up, *dw;
    Row* go(int);
} hd[N * 4], EXT_BOT;
Row* Row::go(int d) {
    Row*r = this;
    if (d < 0) {
        while (d < 0) {
            r = r->dw;
            if (r == NULL) return &EXT_BOT;
            ++d;
        }
    } else {
        while (0 < d) {
            r = r->up;
            --d;
        }
    }
    return r;
}
struct Node {
    Node *dw, *up;
    Row *row;
    int col;
} node_pool[N * 4], *loc, *top[N], *bot[N];
Node* newNode(Row *row, int col) {
    loc->row = row;
    loc->col = col;
    loc->dw = loc->up = NULL;
    return loc++;
}

Row* getPos(int t, int col, int ang) {
    int (*d)[2] = tile[t][ang];
    Row* r;
    int max_h = INT_MIN;
    for (int i = 0; i < 4; ++i) {
        int tcol = col + d[i][1];
        Row *tr = top[tcol]->row->go(-d[i][0]);
        if (tr->h > max_h) {
            max_h = tr->h;
            r = tr;
        }
    }
    return r->up;
}


int main() {
#ifdef lol
    freopen("TETRIS2D.in", "r", stdin);
    freopen("TETRIS2D.out", "w", stdout);
#endif
    EXT_BOT.h = INT_MIN;

    /*
       char brd[10][10 * 4];
       for (int i = 0; i < 7; ++i) {
       printf("On tile %d:\n", i);
       memset(brd, ‘ ‘, sizeof brd);
       for (int j = 0; j < 4; ++j) {
       int row = 5, col = j * 10;
       for (int k = 0; k < 4; ++k)
       brd[row + tile[i][j][k][0]]
       [col + tile[i][j][k][1]] = ‘*‘;
       }
       for (int i = 0; i < 10; ++i, puts(""))
       for (int j = 0; j < 10 * 4; ++j)
       putchar(brd[10 - i - 1][j]);
       puts("");
       }
       return 0;
       */

    int T; scanf("%d", &T);
    for (int cas = 1; cas <= T; ++cas) {
        printf("Case #%d:\n", cas);
        scanf("%d%d", &w, &n);
        loc = node_pool;
        hd[0].dw = NULL;
        hd[0].up = &hd[1];
        hd[0].h = 0;
        hd[0].clear();
        for (int i = 1; i <= n * 4; ++i) {
            hd[i].dw = &hd[i - 1];
            hd[i].up = &hd[i + 1];
            hd[i].h = i;
            hd[i].clear();
        }
        hd[n * 4 + 1].dw = &hd[n * 4];
        for (int i = 0; i < w; ++i)
            bot[i] = top[i] = newNode(&hd[0], i);

        int scr = 0;
        vector<Row*> full;
        while (n--) {
            int t = id(gchar()), col, ang;
            scanf("%d%d", &col, &ang);
            ang /= 90;
            Row* pos = getPos(t, col, ang);
            //printf("Pos : %d\n", pos->h);
            full.clear();
            for (int i = 0; i < 4; ++i) {
                Row*tmp = pos->go(tile[t][ang][i][0]);
                Node*tnd = newNode(tmp, col + tile[t][ang][i][1]);
                tmp->push_back(tnd);
                if ((int)tmp->size() == w)
                    full.push_back(tmp);
                int tcol = col + tile[t][ang][i][1];
                top[tcol]->up = tnd;
                tnd->dw = top[tcol];
                top[tcol] = tnd;
            }
            if (full.size() != 0) {
                scr += getScore(full.size());
                for (auto&&r : full) {
                    for (auto&&i : *r) {
                        i->dw->up = i->up;
                        if (i->up) i->up->dw = i->dw;
                        if (top[i->col] == i)
                            top[i->col] = i->dw;
                    }
                    r->dw->up = r->up;
                    r->up->dw = r->dw;
                }
            }
            /*
            for (Row* t = hd[0].up; t != NULL; t->h = t->dw->h + 1, t = t->up);
            printf("%d", top[0]->row->h);
            for (int i = 1; i < w; ++i) {
                printf(" %d", top[i]->row->h);
            }
            puts("");
            */
        }
        printf("%d\n", scr);
        for (Row* t = hd[0].up; t != NULL; t->h = t->dw->h + 1, t = t->up);
        printf("%d", top[0]->row->h);
        for (int i = 1; i < w; ++i) {
            printf(" %d", top[i]->row->h);
        }
        puts("");
    }
    return 0;
}

 

以上是关于SPOJ TETRIS2D - Exciting Time的主要内容,如果未能解决你的问题,请参考以下文章

FunAug. 19/24 Exciting Rafting & Swimming

FunJul. 20/21 Exciting Rafting & Swimming

FunJun. 30 The Most Exciting Rafting & Dragon Canyon

Codeforces Round #730 (Div. 2) A. Exciting Bets(同余)

为啥我的 SPOJ GCD2 代码在 SPOJ 上出错?

SPOJ 问题 - 这里出了啥问题?