結果

問題 No.708 (+ー)の式
ユーザー akusyounin2412akusyounin2412
提出日時 2019-12-09 20:57:23
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 5,045 bytes
コンパイル時間 1,614 ms
コンパイル使用メモリ 126,236 KB
実行使用メモリ 4,384 KB
最終ジャッジ日時 2023-09-05 09:46:52
合計ジャッジ時間 2,537 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 AC 1 ms
4,384 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 1 ms
4,380 KB
testcase_07 AC 1 ms
4,376 KB
testcase_08 AC 1 ms
4,380 KB
testcase_09 AC 2 ms
4,376 KB
testcase_10 AC 2 ms
4,376 KB
testcase_11 AC 2 ms
4,376 KB
testcase_12 AC 1 ms
4,376 KB
testcase_13 AC 1 ms
4,380 KB
testcase_14 AC 2 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

# include <iostream>
# include <algorithm>
#include <array>
# include <cassert>
#include <cctype>
#include <climits>
#include <numeric>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <tuple>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <chrono>
# include <random>
# include <limits.h>
# include <unordered_map>
# include <unordered_set>
# include <deque>
# include <cstdio>
# include <cstring>
#include <stdio.h>
#include<time.h>
#include <stdlib.h>
#include <cstdint>
#include <cfenv>
#include<fstream>
//#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
long long MOD = 1000000000 + 7;//998244353;
constexpr long long INF = numeric_limits<LL>::max() / 2;
const double PI = acos(-1);
#define fir first
#define sec second
#define thi third
#define debug(x) cerr<<#x<<": "<<x<<'\n'
typedef pair<LL, LL> Pll;
typedef pair<LL, pair<LL, LL>> Ppll;
typedef pair<LL, pair<LL, bitset<100001>>> Pbll;
typedef pair<LL, pair<LL, vector<LL>>> Pvll;
typedef pair<LL, LL> Vec2;
struct Tll { LL first, second, third; };
struct Fll { LL first, second, third, fourd; };
typedef pair<LL, Tll> Ptll;
#define rep(i,rept) for(LL i=0;i<rept;i++)
#define Rrep(i,mf) for(LL i=mf-1;i>=0;i--)
void YN(bool f) {
	if (f)
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
}
void yn(bool f) {
	if (f)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
}
struct Edge { LL to, cost; };
struct edge { LL from, to, cost; };
vector<vector<int>>g;
vector<edge>edges;
vector<Pll>v;
map<Pll, Pll>ma;
set<LL>st;
LL h, w, n, m, k, t, s, p, q, last, cnt, sum, ans, a[210000], b[210000], dp[2100000];
string str, ss;
bool f;
char c;
int di[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
LL plu(LL a,LL b) {
	return a + b;
}
LL minu(LL a, LL b) {
	return a-b;
}
LL multi(LL a, LL b) {
	return a * b;
}
LL _xor(LL a, LL b) {
	return a ^ b;
}
LL _and(LL a, LL b) {
	return a & b;
}
LL _or(LL a, LL b) {
	return a | b;
}
LL how_to(string s) {
	LL ret = 0;
	for (int i = 0; i < s.size(); i++) {
		ret *= 10;
		ret += (s[i]-'0');
	}
	return ret;
}
template<class T>struct operate {
	int p; // 1:(+,-) 2:(*,/)
	char c; // + - * ^ etc...
	function<T(T, T)>f; // +:(a,b)=a+b
	operate() {};
	operate(int _p, char _c, function<T(T, T)>_f) { p = _p, c = _c, f = _f; };
};
template<class T>struct Parser {
	// results
	int root;                       // vals[root] is the answer
	vector<T> vals;                 // value of each node
	vector<int> left, right;        // the index of left-node, right-node
	function<T(string)> how_to_vals;  // evaluation methods
	vector<operate<T>> operators; // all operatorss are single character
	int priority_max = 2;
	// generate nodes
	int newnode(string op, int lp, int rp, T val = T()) {
		bool flag = 0;
		left.push_back(lp); right.push_back(rp);
		for (int i = 0; i < operators.size(); i++)
			if (op.size() == 1 && op[0] == operators[i].c) 
				vals.push_back(operators[i].f(vals[lp], vals[rp])), flag = 1;
		if (flag == 0)
			vals.push_back(val);
		return (int)vals.size() - 1;
	}
	void eval_init(function<T(string)>func) {
		how_to_vals = func;
	}
	void operate_init(operate<T> op) {
		operators.push_back(op);
	}
	// main solver
	T solve(const string &S) {
		int p = 0;
		for (int i = 0; i < operators.size(); i++) priority_max = max(operators[i].p, priority_max);
		root = expr(S, p);
		return vals[root];
	}
	// parser
	int expr(const string &S, int &p, int pri=1) {
		int lp;
		if (pri == priority_max) lp = value(S, p);
		else lp = expr(S, p, pri + 1);
		while (p < (int)S.size()) {
			bool flag = 0;
			for (int i = 0; i < operators.size(); i++) {
				if (S[p] == operators[i].c&&pri == operators[i].p)flag = 1;
			}
			if (!flag)break;
			string op;
			op.push_back(S[p]); ++p;
			if (priority_max == pri) {
				int rp = value(S, p);
				lp = newnode(op, lp, rp);
			}
			else {
				int rp = expr(S, p, pri + 1);
				lp = newnode(op, lp, rp);
			}
		}
		return lp;
	}
	int value(const string &S, int &p) {
		if (S[p] == '(') {
			++p;                    // skip '('
			int lp = expr(S, p);
			++p;                    // skip ')'
			return lp;
		}
		else {
			/* each process */
			string c;
			while (p < S.size()) {
				bool flag = 0;
				for (int i = 0; i < operators.size(); i++)
					if (S[p] == operators[i].c)flag = 1;
				if (S[p] == ')')flag = 1;
				if (S[p] == '(')flag = 1;
				if (flag)break;
				c.push_back(S[p]); ++p;
			};
			return newnode(c, -1, -1, how_to_vals(c));
		}
	}
};

int main() {
	Parser<LL> prs;
	prs.operate_init((operate<LL>(1, '+', plu)));
	prs.operate_init((operate<LL>(1, '-', minu)));
	prs.operate_init((operate<LL>(2, '*', multi)));
	prs.operate_init((operate<LL>(3, '^', _xor)));
	prs.operate_init((operate<LL>(3, '&',_and)));
	prs.operate_init((operate<LL>(3, '|', _or)));
	prs.eval_init(how_to);
	cin >> str;
	prs.solve(str);
	cout << prs.vals[prs.root] << endl;
	return 0;
}
0