絶滅

どうでもいい

yukicoder - No.193

No.193 筒の数式

問題ページ

エラー判定付き加減算パーサを作ってごにょごにょして解いたけど実際のコンテストでこんな面倒くさいコード書くやつはまずいないと思う

整数型とエラーをまとめたのも微妙な気がするし,プログラムの構造化もちゃんと出来てない気がする

どうするのが正しいのかね

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <climits>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <functional>
#include <set>
#include <numeric>
#include <stack>
#include <utility>
#include <time.h>
//#include "util.h"

using namespace std;
typedef unsigned uint;
typedef long long ll;
typedef unsigned long long ull;



//呪文
template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const pair<_KTy, _Ty>& m) { cout << "{" << m.first << ", " << m.second << "}"; return ostr; }
template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const map<_KTy, _Ty>& m) { if (m.empty()) { cout << "{ }"; return ostr;    } cout << "{" << *m.begin(); for (auto itr = ++m.begin(); itr != m.end(); itr++) { cout << ", " << *itr; } cout << "}"; return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const vector<_Ty>& v) { if (v.empty()) { cout << "{ }"; return ostr; } cout << "{" << v.front(); for (auto itr = ++v.begin(); itr != v.end(); itr++) { cout << ", " << *itr; }    cout << "}"; return ostr; }
template <typename _Ty> ostream& operator << (ostream& ostr, const set<_Ty>& s) { if (s.empty()) { cout << "{ }"; return ostr; } cout << "{" << *(s.begin()); for (auto itr = ++s.begin(); itr != s.end(); itr++) { cout << ", " << *itr; }    cout << "}"; return ostr; }
#define PI 3.14159265358979323846
#define EPS 1e-6
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define all(x) (x).begin(), (x).end()



// パーサ.ポインタ pos は常に次に読み込む文字を指すようにする
typedef struct Parser {

    // 解析対象の計算式
    string S;
    // 解析位置
    int pos;

    // コンストラクタ
    Parser() { pos = 0; }
    Parser(string S) { this->S = S; pos = 0; }

} parser;


// エラー判定付き整数型
typedef struct Eint {

    int val;
    bool err;

    Eint() { val = 0; err = false; }

} eint;


bool is_digit(char c)
{
    if ('0' <= c && c <= '9') return true;
    else return false;
}


// 整数を読み込む
eint parse_int(parser& ps)
{
    // いちいち ps. を書かなくていいようにする
    string& S = ps.S;
    int& pos = ps.pos;

    // 読み込み結果を格納するオブジェクト
    eint res;

    // 読み込んだ文字が数字でなければエラー
    if (!is_digit(S[pos])) {
        res.err = true;
        return res;
    }
    
    // 終端到達もしくは数字以外を読み込むまで
    while ( pos != S.size() && is_digit(S[pos]) ) {
        
        res.val *= 10;
        res.val += S[pos] - '0';
        
        pos++;

    }
    
    return res;
}

// 加減算器
eint calc(parser& ps)
{
    string& S = ps.S;
    int& pos = ps.pos;

    // 数字を読み込む
    eint res = parse_int(ps);
    // 数字じゃなかったらエラー
    if (res.err) return res;
    
    // 終端到達まで
    while (pos != S.size()) {
        // 入力データの仮定から確実に演算子
        // 演算子を保持する
        char op = S[pos];
        pos++;

        // 演算子で終わる場合はエラー
        if (pos == S.size()) {
            res.err = true;
            return res;
        }

        // 演算子で終わらない場合は入力データの仮定から
        // 確実に整数が来るのでエラー判定はしない
        if (op == '+')
            // 加算
            res.val += parse_int(ps).val;
        else
            // 減算
            res.val -= parse_int(ps).val;
    }

    return res;
}

// 文字列の回転
void rotate(string& S)
{
    S = S.back() + S;
    S.pop_back();
}

int yuki0193()
{
    int ans = INT_MIN;

    string S;
    cin >> S;
    
    parser ps;

    // 文字列の長さだけ S を回転させて計算すれば全ての場合をつくす
    for (uint i = 0; i <= S.size(); i++) {
        //文字列回転
        rotate(S);
        // パーサ作成
        ps = parser(S);
        // 計算結果の格納
        eint res = calc(ps);
        // エラー処理
        if (res.err) continue;
        // 最大値更新
        if (ans < res.val) ans = res.val;
    }
    
    cout << ans << endl;

    return 0;
}

int main()
{
    //clock_t start, end;
    //start = clock();

    yuki0193();

    //end = clock();
    //printf("%d msec.\n", end - start);

    return 0;
}