萌新刚学 OI,求助水题
查看原帖
萌新刚学 OI,求助水题
298549
SIXIANG32楼主2021/8/23 13:53
#include <iostream> 
#include <string>
#include <stack>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
int M[MAXN + 10];//每个字母的值 
int fuck[MAXN + 10];//符号的优先级 
int pika[MAXN + 10];//start/loop 与 end 的对应关系1 
string comp(string str) {
	fuck['('] = fuck[')'] = -1, fuck['*'] = fuck['/'] = 2, fuck['+'] = fuck['-'] = 1;
	stack <char> sta;
	string qwq = "";
	for(int p = 0; p < str.size(); p++) {
		if(str[p] >= 'a' && str[p] <= 'z') 
			qwq += string(1, str[p]) + " ";
		else if(str[p] >= '0' && str[p] <= '9') {
			int i = p, k = 0;
			string qaq = "";
			while(str[i] >= '0' && str[i] <= '9') qaq += str[i++];
			p = i - 1, qwq += qaq + " ";
		}
		else if(str[p] == '(') sta.push(str[p]);
		else if(str[p] == ')') {
			while(!sta.empty() && sta.top() != '(')
				qwq = qwq + string(1, sta.top()) + " ", sta.pop();
			if(!sta.empty() && sta.top() == '(') sta.pop();
		}
		else {
			while(!sta.empty() && fuck[sta.top()] >= fuck[str[p]])
				qwq = qwq + string(1, sta.top()) + " ", sta.pop(); 
			sta.push(str[p]);
		}
	}
	while(!sta.empty()) qwq = qwq + string(1, sta.top()) + " ", sta.pop();
	return qwq;
}
int expre(string str) {//计算一个中缀表达式 
	str = comp(str); 
	stack <int> sta;
	for(int p = 0; p < str.size(); p++) {
		if(str[p] >= 'a' && str[p] <= 'z') sta.push(M[str[p]]);
		else if(str[p] >= '0' && str[p] <= '9') {
			int i = p, k = 0;
			while(str[i] >= '0' && str[i] <= '9') k = k * 10 + str[i++] - '0';
			p = i, sta.push(k);
		}
		else if(str[p] == '+') {
			int T1 = sta.top(); sta.pop();
			int T2 = sta.top(); sta.pop();
			sta.push(T1 + T2);
		}
		else if(str[p] == '-') {
			int T1 = sta.top(); sta.pop();
			int T2 = sta.top(); sta.pop();
			sta.push(T2 - T1);
		}
		else if(str[p] == '*') {
			int T1 = sta.top(); sta.pop();
			int T2 = sta.top(); sta.pop();
			sta.push(T1 * T2);
		}
		else if(str[p] == '/') {
			int T1 = sta.top(); sta.pop();
			int T2 = sta.top(); sta.pop();
			sta.push(T2 / T1);
		}
	}
	return sta.top();
}
//中缀表达式
int n;
string in[MAXN + 10];//读入 
int init() {
	int n = 0, tot = 1;
	string eat;
	stack <int> sta; sta.push(1), pika[1] = 1;//压入 start 
	while(1) {
		getline(cin, in[++n]);//读入 
		string fk = "";
		int i;
		for(i = 0; i < in[n].size(); i++){
			if(in[n][i] >= 'a' && in[n][i] <= 'z' || in[n][i] >= '0' && in[n][i] <= '9' || in[n][i] == '=' || in[n][i] == '+' || in[n][i] == '-' || in[n][i] == '*' || in[n][i] == '/' || in[n][i] == '(' || in[n][i] == ')')
				break;
		} 
		for(; i < in[n].size(); i++) fk += in[n][i];
		in[n] = fk;//磕掉没用字符 
		if(in[n][0] == 'l' && in[n][1] == 'o') sta.push(n), pika[n] = ++tot;
		else if(in[n][0] == 'e' && in[n][1] == 'n')
			if(!sta.empty()) pika[n] = pika[sta.top()], sta.pop();
		if(pika[n] == 1 && n > 1) break;//匹配 start/loop 的 end,如果匹配到 start 的 end 直接结束 
	}
	n--; 
	//读入  
	return n;
}
//以上是魔法读入
void asment(string str) {
	char name = str[0];//变量名
	string fk = "";
	for(int p = 2; p < str.size(); p++)
		fk += string(1, str[p]);
	M[name] = expre(fk);
}
void write(string str) {
	string fk = "";
	for(int p = 6; p < str.size(); p++) fk += str[p];
	cout << expre(fk) << endl;
}
int loop(int pos) {
	int res = pika[pos];
	string fk = "";
	for(int p = 5; p < in[pos].size(); p++)
		fk = fk + string(1, in[pos][p]);
	int qwq = expre(fk);
	while(qwq--) {
		bool br = 0;
		for(int p = pos + 1; p <= n; p++) {
			if(pika[p] != res) {
				if(in[p][1] == '=') asment(in[p]);//赋值 
				else if(in[p][0] == 'w' && in[p][1] == 'r' && in[p][2] == 'i') write(in[p]);
				else if(in[p][0] == 'l' && in[p][1] == 'o') p = loop(p);
				else if(in[p][0] == 'c' && in[p][1] == 'o') break;
				else if(in[p][0] == 'b' && in[p][1] == 'r') {br = 1; break;}
			}
			else break;
		}
		if(br) break;
	}
	for(int p = pos + 1; p <= n; p++) 
		if(pika[p] == res) return p;
}
void work(int n) {//开始运行 
	for(int p = 1; p <= n; p++) {
		if(in[p] == "start") continue;//开始语句,没啥用 
		else if(in[p][1] == '=') asment(in[p]);//赋值 
		else if(in[p][0] == 'w' && in[p][1] == 'r' && in[p][2] == 'i') write(in[p]);
		else if(in[p][0] == 'l' && in[p][1] == 'o') p = loop(p);
	}
} 
int main() {
	n = init();
	work(n);
}

嗑药大模拟的时候肯定要打一些注释啦,不然的话自己都看不懂(
孩子嗑药磕裂开了,有人给个 Hack 数据或是教教我哪里错了嘛/kel

2021/8/23 13:53
加载中...