洛谷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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值