码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ TETRIS2D - Exciting Time

时间:2017-09-30 19:56:24      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:维护   lol   链表   spoj   max   mda   题意   高度   printf   

数据结构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

标签:维护   lol   链表   spoj   max   mda   题意   高度   printf   

原文地址:http://www.cnblogs.com/ichn/p/7615788.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!