AOJ2613 Unordered Operators
問題
方針
$3$ つの演算子を $a,b,c$ とすると,優先順位は以下の 4 通りしかない. これら全てのパーサを実装する.
- $a > b > c$
- $a = b > c$
- $a > b = c$
- $a = b = c$
もっと頭のいい実装方法もあります.
実装
#include <bits/stdc++.h>
using namespace std;
#define loop(i,a,b) for(int i=(a);i<int(b);i++)
#define rep(i,b) loop(i,0,b)
#define CR const &
typedef long long Val;
Val operate(Val a, Val b, char r){
if(r != '+' && r != '-' && r != '*'){
printf(" %c\n",r);
assert(false);
}
return r=='+' ? a+b : r=='-' ? a-b : a*b;
}
namespace AAA {
pair<Val,int> A(int pos, const char * s);
pair<Val,int> B(int pos, const char * s);
pair<Val,int> A(int pos, const char * s){
Val res;
tie(res,pos) = B(pos,s);
while(s[pos] && (s[pos] == '+' || s[pos] == '-' || s[pos] == '*')){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = B(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> B(int pos, const char * s){
if(s[pos] == '('){
pos++;
pair<Val,int> res = A(pos,s);
res.second++;
return res;
}
if(isdigit(s[pos])){
Val res = 0;
while(isdigit(s[pos])){
res = res*10 + s[pos++]-'0';
}
return make_pair(res,pos);
}
printf(" %d %s %c\n", pos, s, s[pos]);
assert(false);
}
}
namespace AAB {
char a1,a2,b;
pair<Val,int> A(int pos, const char * s);
pair<Val,int> B(int pos, const char * s);
pair<Val,int> C(int pos, const char * s);
pair<Val,int> A(int pos, const char * s){
Val res;
tie(res,pos) = B(pos,s);
while(s[pos] && (s[pos] == a1 || s[pos] == a2)){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = B(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> B(int pos, const char * s){
Val res;
tie(res,pos) = C(pos,s);
while(s[pos] && s[pos] == b){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = C(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> C(int pos, const char * s){
if(s[pos] == '('){
pair<Val,int> res = A(pos+1,s);
res.second++;
return res;
}
if(isdigit(s[pos])){
Val res = 0;
while(isdigit(s[pos])){
res = res*10 + s[pos++]-'0';
}
return make_pair(res,pos);
}
assert(false);
}
}
namespace ABB {
char a,b1,b2;
pair<Val,int> A(int pos, const char * s);
pair<Val,int> B(int pos, const char * s);
pair<Val,int> C(int pos, const char * s);
pair<Val,int> A(int pos, const char * s){
Val res;
tie(res,pos) = B(pos,s);
while(s[pos] && s[pos] == a){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = B(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> B(int pos, const char * s){
Val res;
tie(res,pos) = C(pos,s);
while(s[pos] && (s[pos] == b1 || s[pos] == b2)){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = C(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> C(int pos, const char * s){
if(s[pos] == '('){
pair<Val,int> res = A(pos+1,s);
res.second++;
return res;
}
if(isdigit(s[pos])){
Val res = 0;
while(isdigit(s[pos])){
res = res*10 + s[pos++]-'0';
}
return make_pair(res,pos);
}
assert(false);
}
}
namespace ABC {
char a,b,c;
pair<Val,int> A(int pos, const char * s);
pair<Val,int> B(int pos, const char * s);
pair<Val,int> C(int pos, const char * s);
pair<Val,int> D(int pos, const char * s);
pair<Val,int> A(int pos, const char * s){
Val res;
tie(res,pos) = B(pos,s);
while(s[pos] && s[pos] == a){
char op = s[pos];
pos++;
Val ths;
tie(ths,pos) = B(pos,s);
res = operate(res,ths,op);
}
return make_pair(res,pos);
}
pair<Val,int> B(int pos, const char * s){
Val res;
tie(res,pos) = C(pos,s);
while(s[pos] && s[pos] == b){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = C(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> C(int pos, const char * s){
Val res;
tie(res,pos) = D(pos,s);
while(s[pos] && s[pos] == c){
char op = s[pos];
pos++;
Val rhs;
tie(rhs,pos) = D(pos,s);
res = operate(res,rhs,op);
}
return make_pair(res,pos);
}
pair<Val,int> D(int pos, const char * s){
if(s[pos] == '('){
pair<Val,int> res = A(pos+1,s);
res.second++;
return res;
}
if(isdigit(s[pos])){
Val res = 0;
while(isdigit(s[pos])){
res = res*10 + s[pos++]-'0';
}
return make_pair(res,pos);
}
assert(false);
}
}
int main(){
string s;
while(cin >> s){
Val ans = numeric_limits<Val>::min();
char op[] = "+-*";
sort(op,op+3);
do {
AAB::a1 = ABB::a = ABC::a = op[0];
AAB::a2 = ABB::b1 = ABC::b = op[1];
AAB::b = ABB::b2 = ABC::c = op[2];
ans = max(ans, AAA::A(0,s.c_str()).first);
ans = max(ans, AAB::A(0,s.c_str()).first);
ans = max(ans, ABB::A(0,s.c_str()).first);
ans = max(ans, ABC::A(0,s.c_str()).first);
}while(next_permutation(op,op+3));
cout << ans << endl;
}
}