题解:P12436 [NERC2023] Evaluate It and Back Again

· · 题解

开始

我们观察题目发现只需要用到 +-

注意到

k+k−0

正着读为 p 贡献 2k ,反着读对 q 贡献 0

相反 q 的构造便是:

0−k+k

正着读为 p 贡献 0,反着读对 q 贡献 2k

操作完后就可以得到以下代码:

    p /= 2;
    q /= 2;
    if (p > 0)
        cout << p << "+" << p << "-0+";
    else
        cout << "0" << p << p << "+";
    q = trans(q);
    if (q > 0)
        cout << "0-" << q << "+" << q << "+0";
    else
        cout << -q << q << "-0";

根据上述结论,可以写出如下代码:

#include <bits/stdc++.h>
using namespace std;
#define endl "\n";
#define int long long

int p, q;

int trans(int x) {
    int res = 0;
    while (x)  {
        res = res * 10 + x % 10;
        x /= 10;
    }
    return res;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> p >> q;
    if (p % 2 && q % 2) {
        cout << "1+0+";
        p--;
        q--;
    }
    else if (q % 2) {
        cout << "12+";
        p -= 12;
        q -= 21;
    }
    else if (p % 2) {
        cout << "21+";
        p -= 21;
        q -= 12;
    }
    while (!(p % 10) || !(q % 10)) {
        p -= 2;
        q -= 2;
        cout << "2+";
    }
    p /= 2;
    q /= 2;
    if (p > 0)
        cout << p << "+" << p << "-0+";
    else
        cout << "0" << p << p << "+";
    q = trans(q);
    if (q > 0)
        cout << "0-" << q << "+" << q << "+0";
    else
        cout << -q << q << "-0";
    return 0;
}

注意一个魔鬼细节:

    while (!(p % 10) || !(q % 10)) {
        p -= 2;
        q -= 2;
        cout << "2+";
    }

不加这里会因为前导零错掉所以用 2+ 的方式构造出来。