河南省第4回acm省試合C:式求値逆ポーランド式
9649 ワード
タイトル:
https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1457
タイトル:
Description
Dr.Kongが設計したロボットカードは、加減法演算をマスターした後、最近、関数min(20,23)の値が20、add(10,98)の値が108であることを知っているなど、簡単な関数の評価を学んだ.訓練を経て、Dr.Kongが設計したロボットカードは、ネストされたより複雑な表現を計算することもできます.仮定式は、以下のように簡単に定義することができる:1.正の10進数xは式である.2.xおよびyが式である場合、関数min(x,y)も式であり、その値はx,yの最小数である.3.xとyが式である場合、関数max(x,y)も式であり、その値はx,yの最大数である.4.xとyが式である場合、関数add(x,y)も式であり、その値はx,yの和である.例えば、式max(add(1,2)、7)の値は7である.プログラムを作成して、与えられた式のセットについて、Dr.Kongが正しい答えを算出するのを助けて、カードの計算の正誤を校正してください.Input
最初の行:Nは計算する式の個数(1≦N≦10)を表し、次にN行があり、各行は1つの文字列であり、求められる値を表す式(式には余分なスペースはなく、各行は300文字を超えず、式に現れる10進数は1000を超えない.)Output
出力にはN行があり、各行に1つの式の値が対応しています.Sample Input 3 add(1,2) max(1,999) add(min(1,1000),add(100,99))
Sample Output 3 999 200
考え方:
与えられた文字列を接尾辞式に変換し,add(x,y)をx op y,min,max同理に変換する.逆ポーランド式で解きます
https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1457
タイトル:
Description
Dr.Kongが設計したロボットカードは、加減法演算をマスターした後、最近、関数min(20,23)の値が20、add(10,98)の値が108であることを知っているなど、簡単な関数の評価を学んだ.訓練を経て、Dr.Kongが設計したロボットカードは、ネストされたより複雑な表現を計算することもできます.仮定式は、以下のように簡単に定義することができる:1.正の10進数xは式である.2.xおよびyが式である場合、関数min(x,y)も式であり、その値はx,yの最小数である.3.xとyが式である場合、関数max(x,y)も式であり、その値はx,yの最大数である.4.xとyが式である場合、関数add(x,y)も式であり、その値はx,yの和である.例えば、式max(add(1,2)、7)の値は7である.プログラムを作成して、与えられた式のセットについて、Dr.Kongが正しい答えを算出するのを助けて、カードの計算の正誤を校正してください.Input
最初の行:Nは計算する式の個数(1≦N≦10)を表し、次にN行があり、各行は1つの文字列であり、求められる値を表す式(式には余分なスペースはなく、各行は300文字を超えず、式に現れる10進数は1000を超えない.)Output
出力にはN行があり、各行に1つの式の値が対応しています.Sample Input 3 add(1,2) max(1,999) add(min(1,1000),add(100,99))
Sample Output 3 999 200
考え方:
与えられた文字列を接尾辞式に変換し,add(x,y)をx op y,min,max同理に変換する.逆ポーランド式で解きます
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int N = 1010;
int precedence(char ch)
{
if(ch == '>' || ch == ' || ch == '+') return 1;
else return 0;
}
void reverse_polish(char s[], char sta[])
{
char ts[N];
int k = 0, top = 0;
ts[top++] = '@';
for(int i = 0; s[i]; i++)
{
if(s[i] == '(') ts[top++] = s[i];
else if(s[i] == ')')
{
while(ts[top-1] != '(') sta[k++] = ts[--top];
--top;
}
else if(s[i] == '>' || s[i] == ' || s[i] == '+')
{
while(precedence(ts[top-1]) >= precedence(s[i])) sta[k++] = ts[--top];
ts[top++] = s[i];
}
else if(s[i] >= '0' && s[i] <= '9')
{
while(s[i] >= '0' && s[i] <= '9') sta[k++] = s[i++];
i--;
sta[k++] = ' ';
}
}
while(ts[top-1] != '@') sta[k++] = ts[--top];
sta[k++] = '\0';
}
int Operator(int num1, int num2, char ch)
{
int res;
if(ch == '+') res = num1 + num2;
else if(ch == ') res = min(num1, num2);
else if(ch == '>') res = max(num1, num2);
return res;
}
void solve(char s[])
{
int ts[N];
int top = 0;
for(int i = 0; s[i]; i++)
{
if(s[i] >= '0' && s[i] <= '9')
{
int num = 0;
while(s[i] >= '0' && s[i] <= '9') num = num * 10 + s[i] - '0', i++;
i--;
ts[top++] = num;
}
else if(s[i] != ' ')
{
int num1 = ts[--top], num2 = ts[--top];
ts[top++] = Operator(num2, num1, s[i]);
}
}
printf("%d
", ts[0]);
}
int main()
{
char str[N], s[N], sta[N];
int t;
scanf("%d", &t);
while(t--)
{
scanf("%s", str);
for(int i = 0; str[i]; i++)
{
if(str[i] == ',')
for(int j = i-1; j >= 0; j--)
{
if(str[j] == 'n')
{
str[i] = ';
str[j] = str[j-1] = str[j-2] = '?';
break;
}
else if(str[j] == 'x')
{
str[i] = '>';
str[j] = str[j-1] = str[j-2] = '?';
break;
}
else if(str[j] == 'd')
{
str[i] = '+';
str[j] = str[j-1] = str[j-2] = '?';
break;
}
}
}
memset(s, 0, sizeof s);
int k = 0;
for(int i = 0; str[i]; i++)
if(str[i] != '?') s[k++] = str[i];
//printf("%s
", s);
reverse_polish(s, sta);
solve(sta);
}
return 0;
}