- CSP-S 2005
T4
- @ 2025-9-3 21:32:06
#include<bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
string remove(string s)
{
string res;
for(char c : s){
if(c != ' ') res += c;
}
return res;
}
long long qmi(long long a, long long p)
{
long long res = 1;
while(p)
{
if(p & 1) res = res * a % MOD;
a = a * a % MOD;
p >>= 1;
}
return res;
}
vector<string> torp(string expr, map<char, int> prec)
{
vector<string> output;
stack<char> ops;
string num;
for(int i = 0; i < expr.size(); i++)
{
char c = expr[i];
if(isdigit(c)) num += c;
else {
if(!num.empty()) {
output.push_back(num);
num.clear();
}
if(c == 'a') output.push_back("a");
else if(c == '(') ops.push(c);
else if(c == ')')
{
while(!ops.empty() && ops.top() != '(') {
output.push_back(string(1, ops.top()));
ops.pop();
}
if(!ops.empty() && ops.top() == '(') ops.pop();
}
else
{
//弹出优先级比当前运算符高的
while(!ops.empty() && ops.top() != '(' && prec.at(ops.top()) >= prec.at(c))
{
output.push_back(string(1, ops.top()));
ops.pop();
}
ops.push(c);
}
}
}
if(!num.empty()) output.push_back(num);
while(!ops.empty())
{
output.push_back(string(1, ops.top()));
ops.pop();
}
return output;
}
//计算后缀表达式
int eval(vector<string> rp, int x)
{
stack<int> st; //操作数栈
for(string s : rp)
{
if(s == "a") {
st.push(x); //a替换成x
}
else if(s == "+" || s == "-" || s == "*" || s == "^")
{
int r = st.top(); st.pop();
int l = st.top(); st.pop();
if(s == "+") st.push((l + r) % MOD);
else if(s == "-") st.push((l - r + MOD) % MOD);
else if(s == "*") st.push((1ll*l*r) % MOD);
else if(s == "^") st.push(qmi(l, r));
} else st.push(atoi(s.c_str()));
}
return st.top();
}
int main()
{
srand(time(0)); //初始化随机数种子
map<char, int> prec = {
{'+', 1}, {'-', 1}, {'*', 2}, {'^', 3}
}; //运算符优先级
string s;
getline(cin, s);
s = remove(s); //移除空格
int n;
cin >> n;
cin.ignore();
vector<string> op(n); //选项
for(int i = 0; i < n; i++)
{
getline(cin, op[i]);
op[i] = remove(op[i]);
}
vector<int> test;
for(int i = 0; i < 10; i++)
test.push_back(rand() % 10000);
vector<int> base_v; //题干的表达式预先处理
auto base_rp = torp(s, prec);
// for(string x : base_rp) cout << x << endl;
for(int x : test)
base_v.push_back(eval(base_rp, x));
string res;
for(int i = 0; i < n; i++) //枚举表达式
{
auto rp = torp(op[i], prec); //转化成后缀表达式
bool flag = true; //标记是否等价
for(int j = 0; j < test.size(); j++)
{
int v = eval(rp, test[j]);
if(v != base_v[j]) {
flag = false;
break;
}
}
if(flag) res += (char)('A' + i);
}
cout << res << endl;
return 0;
}
/*
思路:如果直接比较表达式,是否合理?
不合理,因为表达式可能会过于复杂
我们可以通过变量a代入多个不同的值,计算表达式的值是否等价即可。
10个左右的随机数即可。
*/
0 条评论
目前还没有评论...