You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
5.0 KiB
C++
178 lines
5.0 KiB
C++
#include <cctype>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <list>
|
|
#include <stack>
|
|
using namespace std;
|
|
const int MOD = 1000000009;
|
|
inline int fast_pow(int i, int j)
|
|
{
|
|
int ans = 1;
|
|
while (j)
|
|
{
|
|
if (j & 1) ans = (ans * i) % MOD;
|
|
i = (i * i) % MOD;
|
|
j >>= 1;
|
|
}
|
|
return ans;
|
|
}
|
|
struct ENode
|
|
{
|
|
int type /*0=x,1=num,2=op*/, val;
|
|
};
|
|
typedef list<ENode>::iterator ite_type;
|
|
class
|
|
{
|
|
list<ENode> _list;
|
|
char *S, *T;
|
|
#define Next() ((S != T) ? *S++ : -1)
|
|
#define Seek() ((S != T) ? *S : -1)
|
|
#define wrapper(x) ((isdigit((x)) || (x) == 'a' || (x) == '+' || (x) == '-' || (x) == '*' || (x) == '/' || (x) == '(' || (x) == ')' || (x) == '^') ? (x) : -1)
|
|
void Read()
|
|
{
|
|
while (Seek() != -1)
|
|
{
|
|
ENode newNode;
|
|
while (wrapper(Seek()) == -1) Next();
|
|
int x = Seek();
|
|
if (x == 'a')
|
|
{
|
|
newNode.type = 0;
|
|
Next();
|
|
}
|
|
else if (isdigit(x))
|
|
{
|
|
newNode.type = 1, newNode.val = 0;
|
|
while (isdigit(Seek())) newNode.val = newNode.val * 10 + Next() - '0';
|
|
}
|
|
else
|
|
newNode.type = 2,
|
|
newNode.val = Next();
|
|
_list.push_back(newNode);
|
|
}
|
|
}
|
|
int opRank(int ch, bool isInStack)
|
|
{
|
|
if (ch == '+' || ch == '-') return 1;
|
|
if (ch == '*' || ch == '/') return 2;
|
|
if (ch == '(' || ch == ')') return 5;
|
|
if (ch == '^') return 4 - isInStack;
|
|
return -1;
|
|
}
|
|
void Build()
|
|
{
|
|
list<ENode> newList;
|
|
stack<ENode> st;
|
|
for (list<ENode>::iterator cur = _list.begin(); cur != _list.end(); ++cur)
|
|
if (cur->type == 0 || cur->type == 1)
|
|
newList.push_back(*cur);
|
|
else if (cur->val == '(' || st.empty())
|
|
st.push(*cur);
|
|
else if (cur->val == ')')
|
|
{
|
|
while (st.top().val != '(')
|
|
{
|
|
newList.push_back(st.top());
|
|
st.pop();
|
|
}
|
|
st.pop();
|
|
}
|
|
else
|
|
{
|
|
while (!st.empty() && opRank(st.top().val, true) >= opRank(cur->val, false) && st.top().val != '(')
|
|
{
|
|
newList.push_back(st.top());
|
|
st.pop();
|
|
}
|
|
st.push(*cur);
|
|
}
|
|
while (!st.empty())
|
|
{
|
|
newList.push_back(st.top());
|
|
st.pop();
|
|
}
|
|
_list = newList;
|
|
}
|
|
|
|
public:
|
|
list<ENode> operator()(char *beg, char *end)
|
|
{
|
|
_list.clear();
|
|
char *buf = new char[(end - beg) << 1];
|
|
this->S = buf;
|
|
for (char *ptr = beg; ptr != end; ptr++)
|
|
if (!isspace(*ptr)) *buf++ = *ptr;
|
|
this->T = buf;
|
|
int bcnt = 0;
|
|
for (char *ptr = S; ptr != T; ptr++) bcnt += (*ptr == '('), bcnt -= (*ptr == ')');
|
|
for (int i = 0; i < bcnt; i++) *T++ = ')';
|
|
buf = this->S;
|
|
Read();
|
|
delete[] buf;
|
|
Build();
|
|
return this->_list;
|
|
}
|
|
} build;
|
|
int calc(const list<ENode> &expression, int num)
|
|
{
|
|
list<ENode> _list = expression;
|
|
for (list<ENode>::iterator ite = _list.begin(); ite != _list.end(); ++ite)
|
|
if (ite->type == 0)
|
|
ite->type = 1,
|
|
ite->val = num;
|
|
ite_type cur = _list.begin(), p1, p2;
|
|
while (_list.size() > 1)
|
|
{
|
|
if (cur->type == 2)
|
|
{
|
|
p1 = p2 = cur;
|
|
advance(p1, -2);
|
|
advance(p2, -1);
|
|
int x = p1->val;
|
|
int y = p2->val;
|
|
int ch = cur->val;
|
|
_list.erase(p1);
|
|
_list.erase(p2);
|
|
cur->type = 2;
|
|
cur->val = 1;
|
|
if (ch == '+')
|
|
cur->val = (x + y) % MOD;
|
|
if (ch == '-')
|
|
cur->val = x - y;
|
|
if (ch == '*')
|
|
cur->val = (1LL * x * y) % MOD;
|
|
if (ch == '/')
|
|
cur->val = x / y;
|
|
if (ch == '^')
|
|
cur->val = fast_pow(x, y);
|
|
}
|
|
cur++;
|
|
}
|
|
return _list.begin()->val;
|
|
}
|
|
int n;
|
|
char ms[60], ops[30][60];
|
|
list<ENode> mslist, opslst[30];
|
|
bool failed[30];
|
|
int main()
|
|
{
|
|
fgets(ms, 60, stdin);
|
|
scanf("%d\n", &n);
|
|
for (int i = 0; i < n; i++)
|
|
fgets(ops[i], 60, stdin);
|
|
mslist = build(ms, ms + strlen(ms) - 1);
|
|
for (int i = 0; i < n; i++)
|
|
opslst[i] = build(ops[i], ops[i] + strlen(ops[i]) - 1);
|
|
for (int i = 10; i < 20; i++)
|
|
{
|
|
int ans = calc(mslist, i);
|
|
for (int j = 0; j < n; j++)
|
|
if (!failed[j])
|
|
if (calc(opslst[j], i) != ans)
|
|
failed[j] = true;
|
|
}
|
|
for (int i = 0; i < n; i++)
|
|
if (!failed[i])
|
|
putchar('A' + i);
|
|
return 0;
|
|
} |