• 2017 ACM-ICPC Beijing, D


    题意

    给你一个魔改版的跳棋, 模拟操作, 最后输出局面

    做法

    用链表建完棋盘后就很简单了. 一开始写起来比较烦, 最后悟到建棋盘其实就是一个描述过程, 你大可用纯粹用代码来描述, 这不可避免大量的讨论; 也可以用数据来描述, 手动输入每个点六个方向的点是谁, 这枯燥的输入绝对无法正确搞定, 那么其实我应该要做的是trade off, 结合数据和代码来描述, 得到了一个比较好写的做法.

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Cell {
        int r, c; // r: region(1, 2, 3, 4, 5, 6, 0), c: color, occupid by who, 
        Cell *L, *R, *UL, *UR, *LL, *LR;
        Cell() {
            r = c = 0;
            L = R = UL = UR = LL = LR = NULL;
        }
    } cells[20 * 20], *row[20], *loc = cells;
    
    
    Cell*goRight(Cell*x, int d) {
        for (int i = 0; i < d; ++i)
            x = x->R;
        return x;
    }
    
    int num[] = {0, 1, 2, 3, 4, 13, 12, 11, 10, 9, 10, 11, 12, 13, 4, 3, 2, 1};
    int sp[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 5, 1, 1, 1};
    int sc[] = {0, 0, 1, 1, 1, 5, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
    
    void build() {
        Cell *p, *c;
    
        for (int i = 1; i <= 17; ++i)
            row[i] = loc++;
    
        for (int i = 1; i <= 17; ++i) {
            p = row[i];
            for (int j = 1; j <= num[i]; ++j) {
                p->R = loc++;
                if (j != 1)
                    p->R->L = p;
                p = p->R;
            }
        }
    
        for (int i = 2; i <= 17; ++i) {
            p = goRight(row[i - 1]->R, sp[i - 1]);
            c = i == 5 ? goRight(row[i]->R, 4) : row[i]->R;
            while (p && c) {
                c->UR = p;
                p->LL = c;
                p = p->R;
                c = c->R;
            }
        }
    
        for (int i = 2; i <= 17; ++i) {
            c = goRight(row[i]->R, sc[i]);
            p = i == 14 ? goRight(row[i - 1]->R, 4) : row[i - 1]->R;
            while (p && c) {
                c->UL = p;
                p->LR = c;
                p = p->R;
                c = c->R;
            }
        }
    
    }
    
    
    void recolor() {
        Cell*p;
        for (int i = 1; i <= 17; ++i) {
            p = row[i]->R;
            while (p) {
                p->c = 0;
                p = p->R;
            }
        }
    
        for (int i = 1; i <= 4; ++i) {
            p = row[i]->R;
            for (int j = 1; j <= i; ++j) {
                p->c = p->r = 1;
                p = p->R;
            }
        }
    
        for (int i = 5; i <= 8; ++i) {
            p = row[i]->R;
            for (int j = 4; i - 5 < j; --j) {
                p->c = p->r = 6;
                p = p->R;
            }
            p = goRight(row[i]->R, 9);
            for (int j = 4; i - 5 < j; --j) {
                p->c = p->r = 4;
                p = p->R;
            }
        }
    
        for (int i = 10; i <= 13; ++i) {
            p = row[i]->R;
            for (int j = 0; j < i - 9; ++j) {
                p->c = p->r = 3;
                p = p->R;
            }
            p = goRight(row[i]->R, 9);
            for (int j = 0; j < i - 9; ++j) {
                p->c = p->r = 5;
                p = p->R;
            }
        }
    
        for (int i = 14; i <= 17; ++i) {
            p = row[i]->R;
            for (int j = 4; i - 14 < j; --j) {
                p->c = p->r = 2;
                p = p->R;
            }
        }
    }
    
    Cell*go(Cell*c, string dir) {
        if (dir == "L")
            return c->L;
        if (dir == "R")
            return c->R;
        if (dir == "UL")
            return c->UL;
        if (dir == "UR")
            return c->UR;
        if (dir == "LL")
            return c->LL;
        return c->LR;
    }
    
    vector<pair<bool, Cell*> > path;
    int ok_col[7] = {0, 2, 1, 4, 3, 6, 5};
    
    bool sym(int l, int r) {
        for (int i = l, j = r; i < j; ++i, --j)
            if (path[i].first != path[j].first)
                return false;
        if (r < l) return true;
        int cnt = 0;
        for (int i = l; i <= r; ++i)
            if (!path[i].first) ++cnt;
        return cnt > 0;
    }
    
    bool ok(int p, int c) {
        if (path[p].second->r == 0 || path[p].second->r == c || ok_col[path[p].second->r] == c) {
            return path[p].first;
        }
        return false;
    }
    
    vector<pair<int, int> > pos[7];
    
    int go(Cell*c, string dir, int t) {
        if (!c) return t;
        return go(go(c, dir), dir, t + 1);
    }
    
    int main() {
    #ifdef lol
        freopen("d.in", "r", stdin);
        freopen("d.out", "w", stdout);
    #endif
    
        build();
        int r, c, n;
        string dir;
        while (cin >> n) {
            recolor();
            int player = 1;
            while (n--) {
                cin >> r >> c >> dir;
                //cout << r << ' ' << c << ' ' << dir << endl;
                Cell*p = row[r], *t;
                for (int i = 0; i < c; ++i)
                    if (p)
                        p = p->R;
                if (p && p->c == player) {
                    path.clear();
                    t = p;
                    while (t) {
                        path.push_back(make_pair(t->c == 0, t));
                        t = go(t, dir);
                    }
                //    printf("%d
    ", (int)path.size());
                    t = NULL;
                    for (int i = 1; i < (int)path.size(); ++i) {
                        if (sym(1, i - 1) && ok(i, p->c))
                            t = path[i].second;
                    }
                    if (t != NULL) {
                        swap(t->c, p->c);
                //        puts("ok");
                    }
                }
                for (int i = 1; i <= 6; ++i) {
                    pos[i].clear();
                }
                for (int i = 1; i <= 17; ++i) {
                    p = row[i]->R;
                    for (int j = 1; p; p = p->R, ++j) {
                        if (p->c)
                            pos[p->c].push_back(make_pair(i, j));
                    }
                }
                player %= 6;
                ++player;
            }
            for (int i = 1; i <= 6; ++i) {
                sort(pos[i].begin(), pos[i].end());
                for (int j = 0; j < (int)pos[i].size(); ++j)
                    printf("%d %d ", pos[i][j].first, pos[i][j].second);
                puts("");
            }
        }
    
    
        return 0;
    }
  • 相关阅读:
    May Lunchtime 2021 Division 1
    June Cook-Off 2021 Division 1
    Codeforces Round #733 (Div. 1 + Div. 2)
    腾讯云TDSQL MySQL版
    腾讯云TDSQL PostgreSQL版-产品优势
    腾讯云TDSQL PostgreSQL版 -应用场景
    腾讯云TDSQL PostgreSQL版 -最佳实践 |优化 SQL 语句
    腾讯云TDSQL PostgreSQL版 -最佳实践 |优化 SQL 语句
    腾讯云TDSQL监控库密码忘记问题解决实战
    腾讯云分布式数据库TDSQL在银行传统核心系统中的应用实践
  • 原文地址:https://www.cnblogs.com/ichn/p/7881052.html
Copyright © 2020-2023  润新知