Shipura |
Time Limit: 20000ms, Special Time Limit:50000ms, Memory Limit:65536KB |
Total submit users: 17, Accepted users: 14 |
Problem 12817 : No special judgement |
Problem description |
Dr. Suposupo developed a programming language called Shipura. Shipura supports only one binary operator >> and only one unary function S < >. x >> y is evaluated to &lfloor x / 2^y &rfloor (that is, the greatest integer not exceeding x / 2^y), and S< x > is evaluated to x^2 mod 1,000,000,007 (that is, the remainder when x^2 is divided by1,000,000,007). The operator >> is left-associative. For example, the expression x >> y >> z is interpreted as (x >> y) >> z, not as x >> (y >> z). Note that these parentheses do not appear in actual Shipura expressions. The syntax of Shipura is given (in BNF; Backus-Naur Form) as follows: expr ::= term | expr sp ">>" sp term term ::= number | "S" sp "<" sp expr sp ">" sp ::= "" | sp " " number ::= digit | number digit digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" The start symbol of this syntax is \tt expr that represents an expression in Shipura. In addition, number is an integer between 0 and 1,000,000,000 inclusive, written without extra leading zeros. Write a program to evaluate Shipura expressions. |
Input |
The input is a sequence of datasets. Each dataset is represented by a line which contains a valid expression in Shipura. A line containing a single # indicates the end of the input. You can assume the number of datasets is at most 100 and the total size of the input file does not exceed 2,000,000 bytes. OutputFor each dataset, output a line containing the evaluated value of the expression. |
Output |
For each dataset, output a line containing the evaluated value of the expression. |
Sample Input |
S< S< 12 >> 2 > > 123 >> 1 >> 1 1000000000 >>129 S<S<S<S<S<2>>>>> S <S< S<2013 >>> 11 >>> 10 > # |
Sample Output |
81 30 0 294967268 14592400 |
Problem Source |
JAG Practice Contest for ACM-ICPC Asia Regional 2013 |
题意:有两个操作运算符S<x>就是将x平方。a>>b就是将a除以2的b次方次。给出这样的一个字符串。求出结果来。
题解:明显两个操作符可以用存入栈中,使用时再调用出来。注意先得处理完所有空格方便接后的判断。比如遇到S就把S压入栈中(我用的0表示S操作),遇到>号要进行判断,后面位置是数字还是S,如果是数字的话直接进行操作,取出栈中符号,如果是S则将>>操作压入栈中(用1表示>>操作)。如果只有一个>,就取出数字,进行S<x>操作,然后还要进行判断前面符号操作是不是>>(1),如果是则进行>>操作。如此类推。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
using namespace std;
#define N 200010
#define LL __int64
#define M 1000000007
char s[N],ss[N];
stack <LL> num;
stack <LL> go;
LL ksm(LL a,LL b)
{
if (b==0) return a;
for (int i=1;i<=b;i++)
{
a/=2;
if (a==0) return 0;
}
return a;
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("outt.txt","w",stdout);
while (gets(ss))
{
if (ss[0]=='#') break;
while (!num.empty()) num.pop();
while (!go.empty()) go.pop();
LL l=strlen(ss);
LL tt=0;
memset(s,0,sizeof(s));
for (LL i=0;i<l;i++)
{
while (ss[i]==' ') i++;
s[tt++]=ss[i];
}
s[tt]='\0';
int i=0;
l=tt;
while (i<l)
{
if (s[i]=='S')
{
go.push(0);
i+=2;
}
if (s[i]>='0' && s[i]<='9')
{
LL k=0;
while (s[i]>='0' && s[i]<='9')
{
k=(k*10+s[i]-'0') % M;
i++;
}
num.push(k);
}
if (s[i]=='>')
{
i++;
if (!num.empty() && s[i]=='>' && s[i+1]>='0' && s[i+1]<='9')
{
LL k=0;
i++;
while (s[i]>='0' && s[i]<='9')
{
k=(k*10+s[i]-'0') % M;
i++;
}
LL k1=num.top();
num.pop();
num.push(ksm(k1,k));
}
else
{
if (!go.empty() && go.top()==0 && s[i+1]!='S')
{
LL k=num.top();
num.pop();
k=k % M * k % M;
num.push(k);
go.pop();
while (!go.empty() && go.top()==1)
{
k=num.top();
num.pop();
LL k1=num.top();
num.pop();
num.push(ksm(k1,k));
go.pop();
}
}
else
{
go.push(1);
i++;
}
}
}
}
LL k;
k=num.top();
num.pop();
cout<<k<<endl;
}
return 0;
}