求助这是怎么跑起来的
查看原帖
求助这是怎么跑起来的
315554
lusers楼主2023/11/27 23:06

洛谷民间数据 AC,官方数据 50pts(WA+TLE)。

不清楚这个做法为什么能拿到分,也不知道为什么会 WA 和 TLE。

自己测试的时候感觉只要 limbo iteration 迭代次数足够多,就能抛出一个正确的结果,然而似乎并不是这样(

思路和一些细节都在注释里了。

#include <iostream>
#include <numeric>
#include <syncstream>
#include <vector>
using namespace std;

constexpr int VT_T = 0xf4240;
constexpr int VT_F = 0xf4241;
constexpr int VT_U = 0xf4242;

// specifications:
// 1: x_1 initial value
// 2: x_2 initial value
// -3: negation x_3
// --5 is folded to 5
// ---6 is folded to -6
// VT_T is T
// VT_F is F
// VT_U is U
// fin

inline int flip(int a)
{
    if (a == VT_T) {
        return VT_F;
    }
    if (a == VT_F) {
        return VT_T;
    }
    if (a == VT_U) {
        return VT_U;
    }
    return -a;
}

// clang-tidy says:
// Function 'tmain' has cognitive complexity of 37 (threshold 25) [readability-function-cognitive-complexity]
// agree
void tmain()
{
    vector<int>                  vec; // variables, see specifications for value meaning
    vector<tuple<char, int, int>> ops; // statements
    int                          n, m;
    cin >> n >> m;

    vec.resize(n);
    iota(vec.begin(), vec.end(), 1); // initalize variables with their own initial values

    for (int i = 0; i < m; ++i) {
        char op;
        int   x, y;
        cin >> op >> x;

        if (op == 'T') {
            vec[x - 1] = VT_T;
        } else if (op == 'F') {
            vec[x - 1] = VT_F;
        } else if (op == 'U') {
            vec[x - 1] = VT_U;
        } else if (op == '+') {
            cin >> y;
            vec[x - 1] = vec[y - 1];
        } else if (op == '-') {
            cin >> y;
            vec[x - 1] = flip(vec[y - 1]);
        }
        ops.emplace_back(op, x, y);
    }

    // a limbo variable is a reference to a variable's inital variable
    // such as 1, -2
    // not VT_T, VT_F, VT_U
    int lastlimbos{}; // last limbo count
    int inertia = 10; // iteration inertia, just like SA's temperature

    for (auto i : vec) {
        // cout << i << ' ';
        if (i <= n) {
            ++lastlimbos;
        }
    }
    // cout << endl;

    // limbo iteration
    for (int k = 0; k < 2000; ++k) { // breaker at 2000 iterations
        int limbos{};

        // resolve unknown variables
        // if a variable's value is negative of its initial value after running the statements
        // then it's initial value must be unknown
        for (int i = 0; i < n; ++i) {
            if (vec[i] == -(i + 1)) {
                vec[i] = VT_U;
            }
        }

        // execute statements
        for (auto [v, x, y] : ops) {
            if (v == 'T') {
                vec[x - 1] = VT_T;
            } else if (v == 'F') {
                vec[x - 1] = VT_F;
            } else if (v == 'U') {
                vec[x - 1] = VT_U;
            } else if (v == '+') {
                vec[x - 1] = vec[y - 1];
            } else if (v == '-') {
                vec[x - 1] = flip(vec[y - 1]);
            }
        }

        for (auto i : vec) {
            // cout << i << ' ';
            if (i <= n) {
                ++limbos;
            }
        }
        // cout << endl;

        if (limbos < lastlimbos) {
            lastlimbos = limbos;
            ++inertia; // boost velocity, more inertia
            continue; // remove this line if you want no velocity boost
        }
        if (inertia == 0) {
            break; // stopped
        }
        --inertia;
    }

    int ans{};
    for (auto i : vec) {
        if (i == VT_U) {
            ++ans;
        }
    }
    cout << ans << '\n';
}

// never mind this, but if you really care it:
// 
// Synchronizes the output of std::cout by redirecting it to a synchronized buffer.
[[gnu::constructor]] void syncio_routine()
{
    static syncbuf sbuf{cout.rdbuf()};
    cout.rdbuf(&sbuf);
}

int main()
{
    int c, t;
    cin >> c >> t;
    for (int i = 0; i < t; ++i) {
        tmain();
    }
    return 0;
}
2023/11/27 23:06
加载中...