QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#478191#2345. Karel the RobotkarunaWA 106ms7088kbC++179.4kb2024-07-14 18:32:592024-07-14 18:32:59

Judging History

This is the latest submission verdict.

  • [2024-07-14 18:32:59]
  • Judged
  • Verdict: WA
  • Time: 106ms
  • Memory: 7088kb
  • [2024-07-14 18:32:59]
  • Submitted

answer

#include <bits/stdc++.h>
#define ff first
#define ss second
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int SZ = 40;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

// s = 0, e = 1, n = 2, w = 3;

struct state {
    int x, y, d;

    bool operator<(const state &ot) const { 
        return (x != ot.x) ? x < ot.x : (y != ot.y ? y < ot.y : d < ot.d);
    }
};

typedef pair<state, int> fstate;

int n, m, a[SZ][SZ];

bool in(int x, int y) { return 0 <= x && x < n && 0 <= y && y < m; }

state move_m(state st) {
    int nx = st.x + dx[st.d];
    int ny = st.y + dy[st.d];

    if (!in(nx, ny) || a[nx][ny]) return st;
    else return {nx, ny, st.d};
}
state move_l(state st) {
    return {st.x, st.y, (st.d + 1) % 4};
}
bool cond_s(state st) { return st.d == 0; }
bool cond_e(state st) { return st.d == 1; }
bool cond_n(state st) { return st.d == 2; }
bool cond_w(state st) { return st.d == 3; }
bool cond_b(state st) {
    int nx = st.x + dx[st.d];
    int ny = st.y + dy[st.d];
    return !in(nx, ny) || a[nx][ny];
}

map<fstate, fstate> memo; // function name = -1 -> not terminate
set<fstate> ST;

// 0 = m, 1 = l, 2 = call, 3 = if       com
// 0 = s, 1 = e, 2 = n, 3 = w, 4 = b    cond

struct command {
    int com, cond;
    int pos1, pos2;
};

vector<command> body[101010];

fstate run(fstate st) {
    if (ST.find(st) != ST.end()) {
        return memo[st] = {state{0, 0, 0}, -1};
    }
    if (memo.find(st) != memo.end()) return memo[st];

    ST.insert(st);

    auto [px, py, pd] = st.ff;
    int fn = st.ss;

    int pos = 0;
    vector<pii> N;

    bool debug = false;
    // if (fn == 34) {
    //     debug = true;
    // }
    while (pos < body[fn].size()) {
        auto C = body[fn][pos];
        if (debug) {
            cout << "running " << fn << " -> " << px << ' ' << py << ' ' << pd << "?\n";
            cout << "command : " << C.com << ", ";
            cout << "cond : " << C.cond << ", ";
            cout << "pos1 : " << C.pos1 << ", ";
            cout << "pos2 : " << C.pos2 << ", ";
            cout << '\n';
        }
        if (C.com == 2) {
            fstate nst = {state{px, py, pd}, C.cond};
            auto res = run(nst);

            if (res.ss == -1) {
                ST.erase(st);
                return memo[st] = {state{0, 0, 0}, -1};
            }
            else {
                px = res.ff.x;
                py = res.ff.y;
                pd = res.ff.d;
                // tie(px, py, pd) = res.ff;
            }
            bool found = false;
            while (!N.empty() && N.back().ff == pos) {
                pos = N.back().ss;
                N.pop_back();
                found = true;
            }
            if (!found) pos++;
        }
        else if (C.com == 0) {
            auto nst = move_m(state{px, py, pd});
            px = nst.x;
            py = nst.y;
            pd = nst.d;
            // tie(px, py, pd) = move_m(state{px, py, pd});
            bool found = false;
            while (!N.empty() && N.back().ff == pos) {
                pos = N.back().ss;
                N.pop_back();
                found = true;
            }
            if (!found) pos++;
        }
        else if (C.com == 1) {
            auto nst = move_l(state{px, py, pd});
            px = nst.x;
            py = nst.y;
            pd = nst.d;
            // tie(px, py, pd) = move_l(state{px, py, pd});
            bool found = false;
            while (!N.empty() && N.back().ff == pos) {
                pos = N.back().ss;
                N.pop_back();
                found = true;
            }
            if (!found) pos++;
        }
        else if (C.com == 3) {
            int cond = C.cond;
            bool flag;
            state st = {px, py, pd};
            if (cond == 0) flag = cond_s(st);
            if (cond == 1) flag = cond_e(st);
            if (cond == 2) flag = cond_n(st);
            if (cond == 3) flag = cond_w(st);
            if (cond == 4) flag = cond_b(st);

            if (flag) {
                if (C.pos1 == 1) {
                    pos += C.pos2;
                }
                else {
                    if (N.empty() || N.back().ff != pos + C.pos1 - 1)
                        N.push_back({pos + C.pos1 - 1, pos + C.pos2});
                    pos += 1;
                }
            }
            else {
                if (C.pos2 - C.pos1 == 0) {
                    pos += C.pos2;
                }
                else {
                    if (N.empty() || N.back().ff != pos + C.pos2 - 1)
                        N.push_back({pos + C.pos2 - 1, pos + C.pos2});
                    pos += C.pos1;
                }
            }
        }
    }
    // if (!N.empty()) {
    //     cout << "while running function " << fn << "?\n";
    //     for (auto [x, y]: N) {
    //         cout << "if at " << x << " -> " << y << endl;
    //     }
    // }
    assert(N.empty());

    ST.erase(st);
    return memo[st] = {state{px, py, pd}, 0};
}

int main() {
    cin.tie(0); ios_base::sync_with_stdio(0);

    int fcnt = 0, qcnt = 0;

    cin >> n >> m >> fcnt >> qcnt;
    for (int i = 0; i < n; i++) {
        string S;
        cin >> S;
        for (int j = 0; j < m; j++) {
            if (S[j] == '#') a[i][j] = true;
        }
    }
    
    int x[qcnt], y[qcnt], d[qcnt];

    int ffn = 26 + qcnt;
    for (int i = 0; i < fcnt + qcnt; i++) {
        if (i >= fcnt) {
            cin >> x[i - fcnt] >> y[i - fcnt];

            string S;
            cin >> S;
            
            if (S[0] == 's') d[i - fcnt] = 0;
            if (S[0] == 'e') d[i - fcnt] = 1;
            if (S[0] == 'n') d[i - fcnt] = 2;
            if (S[0] == 'w') d[i - fcnt] = 3;
        }

        string S;
        cin >> S;

        int fn = (i < fcnt) ? S[0] - 'A' : 26 + (i - fcnt);
        if (i < fcnt) S = S.substr(2);

        vector<command> ST;

        // cout << S << endl;

        for (int j = 0; j < S.size(); j++) {
            // cout << "while processing " << S[j] << endl;

            if (S[j] == 'm') ST.push_back({0, 0, 0, 0});
            else if (S[j] == 'l') ST.push_back({1, 0, 0, 0});
            else if ('A' <= S[j] && S[j] <= 'Z') {
                ST.push_back({2, S[j] - 'A', 0, 0});
            }
            else if (S[j] == 'i') {
                int cond;
                if (S[j + 1] == 's') cond = 0;
                if (S[j + 1] == 'e') cond = 1;
                if (S[j + 1] == 'n') cond = 2;
                if (S[j + 1] == 'w') cond = 3;
                if (S[j + 1] == 'b') cond = 4;
                j += 2;

                ST.push_back({3, cond, 0, 0});
            }
            else if (S[j] == 'u') {
                int cond;
                if (S[j + 1] == 's') cond = 0;
                if (S[j + 1] == 'e') cond = 1;
                if (S[j + 1] == 'n') cond = 2;
                if (S[j + 1] == 'w') cond = 3;
                if (S[j + 1] == 'b') cond = 4;
                j += 2;

                ST.push_back({4, cond, 0, 0});
            }
            else if (S[j] == ')') {
                vector<command> TM;

                while (!ST.empty() && ((ST.back().com != 3 || ST.back().pos1 != 0) && ST.back().com != 4 && ST.back().com != 5)) {
                    TM.push_back(ST.back());
                    ST.pop_back();
                }
                reverse(TM.begin(), TM.end());

                command C = ST.back();            
                ST.pop_back(); 

                if (C.com == 3) {
                    ST.push_back(C);
                    int pp = (int)ST.size() - 1;

                    for (auto x : TM) ST.push_back(x);
                    ST[pp].pos1 = (int)TM.size() + 1;

                    ST.push_back({5, pp, 0, 0});
                    j++;
                }
                else if (C.com == 5) {
                    int pp = C.cond;
                    for (auto x : TM) ST.push_back(x);
                    ST[pp].pos2 = ST[pp].pos1 + (int)TM.size();
                }
                else if (C.com == 4) {
                    ST.push_back({2, ffn, 0, 0});

                    body[ffn].push_back({3, C.cond, 1, 2 + TM.size()});
                    for (auto x : TM) body[ffn].push_back(x);
                    body[ffn].push_back({2, ffn, 0, 0});
                    ++ffn;
                }
            }
        }
        for (auto x : ST) body[fn].push_back(x);
    }

    // for (int i = 0; i < ffn; i++) {
    //     if (body[i].empty()) continue;

    //     cout << "function " << i << " -> \n";
    //     for (auto C : body[i]) {
    //         cout << "command : " << C.com << ", ";
    //         cout << "cond : " << C.cond << ", ";
    //         cout << "pos1 : " << C.pos1 << ", ";
    //         cout << "pos2 : " << C.pos2 << ", ";
    //         cout << '\n';
    //     }
    // }

    for (int i = fcnt; i < fcnt + qcnt; i++) {
        state st = {x[i - fcnt] - 1, y[i - fcnt] - 1, d[i - fcnt]};

        auto res = run({st, 26 + i - fcnt});
        if (res.ss == -1) {
            cout << "inf\n";
        }
        else {
            auto [x, y, d] = res.ff;

            char ch[4] = {'s', 'e', 'n', 'w'};
            cout << x + 1 << ' ' << y + 1 << ' ' << ch[d] << '\n';
        }
    }
}

Details

Test #1:

score: 100
Accepted
time: 1ms
memory: 6216kb

Test #2:

score: 0
Accepted
time: 1ms
memory: 5912kb

Test #3:

score: 0
Accepted
time: 1ms
memory: 5996kb

Test #4:

score: 0
Accepted
time: 1ms
memory: 5972kb

Test #5:

score: 0
Accepted
time: 1ms
memory: 6164kb

Test #6:

score: 0
Accepted
time: 2ms
memory: 5992kb

Test #7:

score: 0
Accepted
time: 106ms
memory: 7088kb

Test #8:

score: -100
Wrong Answer
time: 3ms
memory: 6568kb