zoukankan      html  css  js  c++  java
  • SPOJ TETRIS2D

    数据结构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 == '
    ' || 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:
    ", 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:
    ", 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
    ", 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
    ", 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;
    }
  • 相关阅读:
    【常用配置】Spring框架web.xml通用配置
    3.从AbstractQueuedSynchronizer(AQS)说起(2)——共享模式的锁获取与释放
    2.从AbstractQueuedSynchronizer(AQS)说起(1)——独占模式的锁获取与释放
    1.有关线程、并发的基本概念
    0.Java并发包系列开篇
    SpringMVC——DispatcherServlet的IoC容器(Web应用的IoC容器的子容器)创建过程
    关于String的问题
    Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
    <<、>>、>>>移位操作
    System.arraycopy(src, srcPos, dest, destPos, length) 与 Arrays.copyOf(original, newLength)区别
  • 原文地址:https://www.cnblogs.com/ichn/p/7615788.html
Copyright © 2011-2022 走看看