【UVA-512】Spreadsheet Tracking【紫书】

【UVA-512】Spreadsheet Tracking【紫书】

问题链接:https://vjudge.net/problem/UVA-512

Solution:

不需要模拟,提前把操作存储下来,之后每一次查询顺着遍历一次操作就好。

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

const int LIM = 10;
const int NIL = -1;
enum {EX, DC, DR, IC, IR};
struct Operation {
    int t, val[LIM];
};
struct Node {
    int r, c;
};
vector<Operation> ops;

int main(void) {
    Operation tmp;
    Node tnode;
    char op[3];
    int n, R, C, a;
    for (int k = 1; ~scanf("%d%d", &R, &C) && R && C; k++) {
        if (k - 1) putchar('\n');
        printf("Spreadsheet #%d\n", k);
        ops.clear();
        scanf("%d", &n);
        while (n--) {
            memset(tmp.val, NIL, sizeof(int) * LIM);
            scanf("%s", op);
            if (!strcmp(op, "EX")) tmp.t = EX;
            else if (!strcmp(op, "DC")) tmp.t = DC;
            else if (!strcmp(op, "DR")) tmp.t = DR;
            else if (!strcmp(op, "IC")) tmp.t = IC;
            else if (!strcmp(op, "IR")) tmp.t = IR;
            if (tmp.t != EX) scanf("%d", &a);
            else a = 4;
            for (int i = 0; i < a; i++) scanf("%d", tmp.val + i);
            ops.push_back(tmp);
        }
        scanf("%d", &n);
        while (n--) {
            scanf("%d%d", &tnode.r, &tnode.c);
            Node bak = tnode;
            bool flag = true;
            int cnt;
            for (int i = 0; i < ops.size(); i++) {
                cnt = 0;
                if (ops[i].t == EX) {
                    if (ops[i].val[0] == tnode.r && ops[i].val[1] == tnode.c)
                        tnode.r = ops[i].val[2], tnode.c = ops[i].val[3];
                    else if (ops[i].val[2] == tnode.r && ops[i].val[3] == tnode.c)
                        tnode.r = ops[i].val[0], tnode.c = ops[i].val[1];
                } else {
                    for (int j = 0; j < LIM; j++) {
                        if (ops[i].val[j] == NIL) break;
                        if (ops[i].t == DC && ops[i].val[j] == tnode.c) {
                            flag = false;
                            break;
                        }
                        if (ops[i].t == DR && ops[i].val[j] == tnode.r) {
                            flag = false;
                            break;
                        }
                        if ((ops[i].t == DC || ops[i].t == IC) && ops[i].val[j] <= tnode.c) cnt++;
                        if ((ops[i].t == DR || ops[i].t == IR) && ops[i].val[j] <= tnode.r) cnt++;
                    }
                    if (!flag) {
                        printf("Cell data in (%d,%d) GONE\n", bak.r, bak.c);
                        break;
                    }
                    if (ops[i].t == DR) tnode.r -= cnt;
                    else if (ops[i].t == DC) tnode.c -= cnt;
                    else if (ops[i].t == IR) tnode.r += cnt;
                    else tnode.c += cnt;
                }
            }
            if (flag) printf("Cell data in (%d,%d) moved to (%d,%d)\n", bak.r, bak.c, tnode.r, tnode.c);
        }
    }
    return 0;
}