yukicoder
次のyukicoderの問題へ
前のyukicoderの問題へ
yukicoder 2927 Reverse Polish Equation
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 5");
WillReturn.Add("X 2 +");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("7 9");
WillReturn.Add("X X 3 max + 11 min");
//-1
}
else if (InputPattern == "Input3") {
WillReturn.Add("11 10");
WillReturn.Add("X X X X X + + + + 10 max");
//0
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long Y = wkArr[1];
string[] ExpArr = InputList[1].Split(' ');
decimal Result0 = ExecCalc(0, ExpArr);
if (Result0 == Y) {
Console.WriteLine(0);
return;
}
if (Result0 > Y) {
Console.WriteLine(-1);
return;
}
if (ExecCalc(Y, ExpArr) < Y) {
Console.WriteLine(-1);
return;
}
long L = 0;
long R = Y;
while (L + 1 < R) {
long Mid = (L + R) / 2;
if (ExecCalc(Mid, ExpArr) >= Y) {
R = Mid;
}
else {
L = Mid;
}
}
decimal Result = ExecCalc(R, ExpArr);
if (Result == Y) {
Console.WriteLine(R);
}
else {
Console.WriteLine(-1);
}
}
// Xの値と、文字列を引数として、計算結果を返す
static decimal ExecCalc(long pX, string[] pExpArr)
{
var Stk = new Stack<decimal>();
foreach (string EachExp in pExpArr) {
if (EachExp == "+" || EachExp == "min" || EachExp == "max") {
decimal Popped1 = Stk.Pop();
decimal Popped2 = Stk.Pop();
decimal CalcResult = 0;
if (EachExp == "+") CalcResult = Popped1 + Popped2;
if (EachExp == "min") CalcResult = Math.Min(Popped1, Popped2);
if (EachExp == "max") CalcResult = Math.Max(Popped1, Popped2);
Stk.Push(CalcResult);
}
else {
if (EachExp == "X") {
Stk.Push(pX);
}
else {
Stk.Push(decimal.Parse(EachExp));
}
}
}
return Stk.Peek();
}
}
解説
オペランドが、+とminとmaxしかないので
計算結果は、Xに対して、広義単調増加です。
なので、二分探索で解けます。