题解:P12601 旷野小计算

· · 题解

六个寄存器,真空指令集。\ 限制卡得紧,一堆子问题。\ 先乘解决除,取负能造一。\ 分支不让用,咋判二的幂。\ 与上零负一,创造新奇迹。\ 数除动分母,官解太诡异。\ 溢出不用急,偶数先右移。\ 一错调一天,这题真猎奇。

附件:作者写的编译器(在调)

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
#define int long long
set<string,int> reg;
int r[10];
signed main()
{
    reg["a"] = reg["rax"] = 1;
    reg["b"] = reg["rbx"] = 2;
    reg["c"] = reg["rcx"] = 3;
    reg["d"] = reg["rdx"] = 4;
    reg["x"] = reg["rsi"] = 5;
    reg["y"] = reg["rdi"] = 6;
    SetConsoleOutputCP(65001);
    cout << "请输入取值数:";
    int val;
    cin >> val;
    if(val == 1)
    {
        string clean;
        getline(cin,clean);
        int _x;
        cout << "请输入一号参数的值:";
        cin >> _x;
        getline(cin,clean);
        cout << "请输入代码行数:";
        int line;
        cin >> line;
        getline(cin,clean);
        cout << "请逐行输入代码:";
        r[reg["x"]] = _x;
        for(int i = 1;i <= line;i++)
        {
            cout << ">> ";
            string c1,c2,c3;
            int c4;
            cin >> c1 >> c2;
            if(c1 == "+" || c1 == "add")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] += r[reg[c3]];
            }
            else if(c1 == "-" || c1 == "sub")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] -= r[reg[c3]];
            }
            else if(c1 == "^" || c1 == "xor")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] ^= r[reg[c3]];
            }
            else if(c1 == "<" || c1 == "shl")
            {
                cin >> c4;
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] <<= c4;
            }
            else if(c1 == ">" || c1 == "shr")
            {
                cin >> c4;
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] >>= c4;
            }
            else if(c1 == "!" || c1 == "write")
            {
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                cout << "输出结果:" << " " << r[reg[c2]] << endl;
            }
            else
            {
                cout << "\n\n第 " << i << " 行发生错误:非法操作";
                return 0;
            }
            getline(cin,clean);
        }
    }
    else
    {
        int _x,_y;
        cout << "请输入一号参数和二号参数的值:";
        cin >> _x >> _y;
        getline(cin,clean);
        cout << "请输入代码行数:";
        int line;
        cin >> line;
        getline(cin,clean);
        cout << "请逐行输入代码:";
        r[reg["x"]] = _x;
        r[reg["y"]] = _y;
        for(int i = 1;i <= line;i++)
        {
            cout << ">> ";
            string c1,c2,c3;
            int c4;
            cin >> c1 >> c2;
            if(c1 == "+" || c1 == "add")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] += r[reg[c3]];
            }
            else if(c1 == "-" || c1 == "sub")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] -= r[reg[c3]];
            }
            else if(c1 == "^" || c1 == "xor")
            {
                cin >> c3;
                if(reg[c2] * reg[c3] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] ^= r[reg[c3]];
            }
            else if(c1 == "<" || c1 == "shl")
            {
                cin >> c4;
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] <<= c4;
            }
            else if(c1 == ">" || c1 == "shr")
            {
                cin >> c4;
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                r[reg[c2]] >>= c4;
            }
            else if(c1 == "!" || c1 == "write")
            {
                if(reg[c2] == 0)
                {
                    cout << "\n\n第 " << i << " 行发生错误:出现未知的寄存器";
                    return 0;
                }
                cout << "输出结果:" << " " << r[reg[c2]] << endl;
            }
            else
            {
                cout << "\n\n第 " << i << " 行发生错误:非法操作";
                return 0;
            }
            getline(cin,clean);
        }
    }
    return 0;
}

正文:

1 号测试点

满分代码行数:不超过 5

考虑通过 x(2^{12} - 2^4) 构造 4080x。\ 于是得到程序如下:

+ a x
< a 12
+ b x
< b 4
- a b
! a

交上去之后,能拿 9 分。

后来我才tmd发现,x 在被 b 读取后不会再被使用。\ 因此,只需在赋值处省略一行代码即可。\ md我怎么这么sb,搞了半小时才发现

满分程序:

+ a x
< a 12
< x 4
- a x
! a