洛谷P4911 河童重工的计算机
题目背景
河童重工业会社的计算机产品在幻想乡中有着极其广泛的应用。
有一天,妖怪之山发大水啦!洪水夹杂着泥沙和滚木汹涌着冲进了河童的城市。
本来河童们的机械设施都是防水的,可是洪水还是对城市造成了不小的破坏。其中,河童们的服务器被砸坏了!
坏掉的电脑在短时间内不能修复,可是幻想乡里的许多事情都离不开河童们的服务器!河童们也很无奈,于是荷取找到了你!你作为一名优秀的信竞选手,决定帮助荷取,减轻服务器故障所带来的压力。
题目描述
你从荷取那里得到了一份纸质资料,扫描版在这里:
Ktx-65式微处理器汇编语言规范文件.pdf
(若此网站无法打开,请在附件中下载)
(为什么说是扫描版呢,因为,你应该不能复制里面的文字)
以下这一段是汇编教程附带的示例:
[ progfunc.asm ]
[ Shows the function functionailties of the KTX-65 ALI ]
[main]
wint #line; [output the current physical line number]
wch 13; [putchar \r]
wch 10; [putchar \n]
callfunc $Function1;
callfunc $Function2;
hlt; [halt]
function $Function1;
rint %r1; [read int]
add %r2 1 %r2; [loop contents]
lle %r2 %r1; [loop conditions]
jif 2; [end loop conditional jump]
wint %r2; [output int]
wch 13; [putchar \r]
wch 10; [putchar \n]
ret; [return]
function $Function2;
rint %r1; [read int]
rint %r2; [read int]
add %r1, %r2; [add]
wint %val; [output value]
wch 13; [putchar \r]
wch 10; [putchar \n]
ret; [return]
你需要用洛谷评测机支持的语言编写一个程序,它读入一个Ktx-65汇编语言程序和一段输入,解释运行这个程序,然后输出这个程序输出的东西。
输入格式
第一行是一个整数N,表示汇编程序的行数。
接下来N行是这个汇编程序,保证不会出现空行。
接下来的所有行都是这个汇编程序的输入。
输出格式
一堆东西,表示这个汇编程序的输出。
评测系统将以逐字节比较的方式判断你的输出是否正确。 假的,洛谷不支持。
输入输出样例
输入 #1复制
5
rint %r1;
rint %r2;
add %r1 %r2;
wint;
hlt;
5 4
输出 #1复制
9
说明/提示
注意:样例输出中只有9这一个字节。
对于10%的数据:程序中只有输入和输出的指令,且不会出现数字常量,也不会有注释。
对于另外10%:程序中只有输入、输出和加法指令,且没有注释。
对于另外30%:包括除函数调用和跳转在内的所有指令。
对于剩下50%:指令没有限制。
对于全部的数据:命令条数不超过50000条,剩余输入不超过500千字节,程序需要执行的步数不超过80000步。
保证汇编程序和数据不出现编译或是运行时错误。
保证程序输入足够满足汇编程序中读入的需要。
不保证这是或不是一道毒瘤题
不保证考试时会不会有人AC这道题
不保证这次考试会不会有人AK
保证出题人为:洩矢诹访子
考试时打不开河童给的文件可以向我索要,不保证是否会回答
其实这道题数据非常简单,只是量大而已
上代码:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#ifdef LOCAL
#define debug(format, args...) \
printf(format, ##args)
#else
#define debug(format, args...)
#endif
using namespace std;
typedef map<string, int> msi;
typedef map<int, int> mii;
typedef stringstream SS;
msi op2fun = {{"udef", 0}, {"hlt", 1}, {"nop", 2}, {"set", 3}, {"jmp", 4},
{"jif", 5}, {"call", 6}, {"ret", 7}, {"inv", 8}, {"add", 9}, {"sub", 10},
{"mult", 11}, {"idiv", 12}, {"mod", 13}, {"lsft", 14}, {"rsft", 15},
{"band", 16}, {"bor", 17}, {"bxor", 18}, {"lgr", 19}, {"lls", 20},
{"lge", 21}, {"lle", 22}, {"leql", 23}, {"land", 24}, {"lor", 25},
{"rint", 26}, {"rch", 27}, {"wint", 28}, {"wch", 29}, {"function", 30}, {"callfunc", 31}};
msi reg2pointer = {{"r1", 0}, {"r2", 1}, {"r3", 2}, {"r4", 3}, {"e1", 4},
{"e2", 5}, {"e3", 6}, {"e4", 7}, {"flag", 8}, {"val", 9}, {"ret", 10}, {"line", 11}};
mii funLine;
mii funIndex;
msi funNum;
mii line2index;
int r1, r2, r3, r4, e1, e2, e3, e4, flag, val, ret, line, falseVar, funCnt = 0, statementCnt = 0;
int *reg[] = {&r1, &r2, &r3, &r4, &e1, &e2, &e3, &e4, &flag, &val, &ret, &line};
int ram[(1 << 23) + 9];
int sAddr[(1 << 19) + 9];
struct data{
int* a;
int value;
int type;
void out(){
debug("\t%d %d\n", value, type);
}
data (int *A = &falseVar, int v = 0, int t = -1): a(A), value(v), type(t){
}
void init(string &s, int L){
auto it = s.begin();
if (s[0] == '%'){
type = 0;
s.erase(it);
a = reg[reg2pointer[s]];
}
else if (s[0] == '@'){
if (s[1] == '%'){
type = 3;
s.erase(it);
s.erase(it);
a = reg[reg2pointer[s]];
}
else{
type = 2;
s.erase(it);
value = stoi(s);
a = &ram[value];
}
}
else if (s[0] == '#'){
a = &falseVar;
value = L;
type = 4;
}
else{
type = 1;
a = &falseVar;
value = stoi(s);
}
}
};
struct op{
int op;
data d[3];
int line, funLine;
};
int getValue(const op &a, int index){
int b = 0;
switch (a.d[index].type){
case 0:{
}
case 2:{
b = *(a.d[index].a);
break;
}
case 3:{
b = ram[*(a.d[index].a)];
break;
}
case 1:{
b = a.d[index].value;
break;
}
case 4:{
b = a.line;
break;
}
}
return b;
}
void fun0(const op &a, int &index){
}
void fun1(const op &a, int &index){
}
void fun2(const op &a, int &index){
}
void fun3(const op &a, int &index){
int b = getValue(a, 0);
*(a.d[1].a) = b;
debug("\nFun3: b: %d line: %X %X;\n", b, *(a.d[1].a), &line);
}
void fun4(const op &a, int &index){
int b = getValue(a, 0);
index = line2index[line + b];
}
void fun5(const op &a, int &index){
int Flag = getValue(a, 1);
int b = getValue(a, 0);
if (Flag){
index = line2index[line + b] - 1;
}
}
void fun6(const op &a, int &index){
int &top = sAddr[0];
top++;
sAddr[top] = index;
debug("PushIndex: %d\n", index + 1);
top++;
sAddr[top] = line;
int b = getValue(a, 0);
index = line2index[b] - 1;
}
void fun7(const op &a, int &index){
int &top = sAddr[0];
int Line = sAddr[top];
line = Line;
top--;
int next = sAddr[top];
top--;
index = next;
debug("NextIndex: %d\n", next);
if (a.d[0].value != -1){
int b = getValue(a, 0);
ret = b;
}
}
void fun8(const op &a, int &index){
int b = getValue(a, 0);
b = -b;
*(a.d[1].a) = b;
}
void fun9(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b + c;
debug("\nFun9: b: %d c: %d ans: %d;\n", b, c, *(a.d[1].a));
}
void fun10(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b - c;
}
void fun11(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b * c;
}
void fun12(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b / c;
}
void fun13(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b % c;
}
void fun14(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b << c;
}
void fun15(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b >> c;
}
void fun16(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b & c;
}
void fun17(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b | c;
}
void fun18(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b ^ c;
}
void fun19(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = (b > c);
}
void fun20(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = (b < c);
}
void fun21(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = (b >= c);
}
void fun22(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = (b <= c);
}
void fun23(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = (b == c);
}
void fun24(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b && c;
}
void fun25(const op &a, int &index){
int b = getValue(a, 0);
int c = getValue(a, 1);
*(a.d[2].a) = b || c;
}
void fun26(const op &a, int &index){
cin >> *(a.d[0].a);
}
void fun27(const op &a, int &index){
cin >> *(a.d[0].a);
}
void fun28(const op &a, int &index){
cout << getValue(a, 0);
}
void fun29(const op &a, int &index){
cout << (char)getValue(a, 0);
}
void fun30(const op &a, int &index){
line = a.line;
debug("Line: %d\n", line);
}
void fun31(const op &a, int &index){
int b = funIndex[a.d[0].value];
debug("b: %d\n", b);
int &top = sAddr[0];
top++;
sAddr[top] = index;
debug("PushIndex: %d\n", index + 1);
top++;
sAddr[top] = line;
index = b - 1;
}
void (*fun[])(const op &a, int &index) = {
fun0, fun1, fun2, fun3, fun4, fun5, fun6, fun7, fun8, fun9,
fun10, fun11, fun12, fun13, fun14, fun15, fun16, fun17, fun18, fun19,
fun20, fun21, fun22, fun23, fun24, fun25, fun26, fun27, fun28, fun29,
fun30, fun31
};
typedef vector<op> vo;
int main(){
#ifndef LOCAL
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
int n;
cin >> n;
cin.get();
vo ops;
int funFlag = 0;
for (int i = 0; i < n; i++){
string line;
getline(cin, line, '\n');
transform(line.begin(), line.end(), line.begin(), ::tolower);
auto it = line.begin();
int zkh = 0;
for (; it < line.end(); it++){
if (zkh){
if (*it == ']'){
zkh--;
}
line.erase(it);
it--;
}
else{
if (*it == ','){
*it = ' ';
}
else if (*it == ';'){
*it = '\n';
}
else if (*it == '['){
zkh++;
line.erase(it);
it--;
}
}
}
SS ss(line);
string s;
while (getline(ss, s, '\n')){
SS ssTemp(s);
string command;
ssTemp >> command;
if (command.empty()){
continue;
}
string sTemp;
int cmd = op2fun[command];
if (!line2index.count(i)){
line2index[i] = statementCnt;
}
switch (cmd){
case 0:{
}
case 1:{
}
case 2:{
op T;
T.op = cmd;
T.line = i;
ops.push_back(T);
break;
}
case 5:{
string a, b;
int cnt = 0;
op T;
T.op = cmd;
T.line = i;
ssTemp >> a;
T.d[0].init(a, i);
if (!(ssTemp >> b) || b.empty()){
string fake = "%flag";
T.d[1].init(fake, i);
}
ops.push_back(T);
break;
}
case 7:{
op T;
T.op = cmd;
T.line = i;
string a;
if (ssTemp >> a && !a.empty()){
}
else{
a = "%ret";
}
T.d[0].init(a, i);
ops.push_back(T);
break;
}
case 4:{
}
case 6:{
op T;
T.op = cmd;
T.line = i;
string a;
ssTemp >> a;
T.d[0].init(a, i);
ops.push_back(T);
break;
}
case 8:{
string a, b;
ssTemp >> a;
if (ssTemp >> b && !b.empty()){
}
else{
b = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[1].init(b, i);
ops.push_back(T);
break;
}
case 3:{
string a, b;
ssTemp >> a >> b;
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[1].init(b, i);
ops.push_back(T);
break;
}
case 9:{
}
case 10:{
}
case 11:{
}
case 12:{
}
case 13:{
}
case 14:{
}
case 15:{
}
case 16:{
}
case 17:{
}
case 18:{
string a, b, c;
ssTemp >> a >> b;
if (ssTemp >> c && !c.empty()){
}
else{
c = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[1].init(b, i);
T.d[2].init(c, i);
ops.push_back(T);
break;
}
case 19:{
}
case 20:{
}
case 21:{
}
case 22:{
}
case 23:{
}
case 24:{
}
case 25:{
string a, b, c;
ssTemp >> a >> b;
if (ssTemp >> c){
}
else{
c = "%flag";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[1].init(b, i);
T.d[2].init(c, i);
ops.push_back(T);
break;
}
case 26:{
string a;
if (ssTemp >> a && !a.empty()){
}
else{
a = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[0].type = 5;
ops.push_back(T);
break;
}
case 27:{
string a;
if (ssTemp >> a && !a.empty()){
}
else{
a = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
T.d[0].type = 6;
ops.push_back(T);
break;
}
case 28:{
string a;
if (ssTemp >> a && !a.empty()){
}
else{
a = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
//T.d[0].type = 7;
ops.push_back(T);
break;
}
case 29:{
string a;
if (ssTemp >> a && !a.empty()){
}
else{
a = "%val";
}
op T;
T.op = cmd;
T.line = i;
T.d[0].init(a, i);
//T.d[0].type = 8;
ops.push_back(T);
break;
}
case 30:{
string a;
ssTemp >> a;
op T;
T.op = cmd;
T.line = i;
int num = 0;
if (!funNum.count(a)){
num = funNum[a] = funCnt++;
}
else{
num = funNum[a];
}
funIndex[num] = ops.size();
funFlag = 1;
T.d[0].value = i;
T.d[0].type = 10;
ops.push_back(T);
break;
}
case 31:{
string a;
ssTemp >> a;
op T;
T.op = cmd;
T.line = i;
int num = 0;
if (!funNum.count(a)){
funNum[a] = funCnt++;
}
num = funNum[a];
T.d[0].value = num;
T.d[0].type = 1;
ops.push_back(T);
break;
}
}
statementCnt++;
}
}
line = ops[0].line;
for (int i = 0; i < statementCnt; i++){
if (ops[i].op == 1){
return 0;
}
else{
fun[ops[i].op](ops[i], i);
debug("\n| op: %d; r1: %d; r2: %d; val: %d; line: %d; %%line: %d; index: %d; |\n",
ops[i].op, r1, r2, val, ops[i].line, line, i);
}
}
return 0;
}