题意
题目链接: https://ac.nowcoder.com/acm/contest/19859/V
计算表达式仅有,0-9、+、-、*、/、^、!字符组成(表达式均合法),优先级! > ^ > *,/ > +, -
一切数值计算均受限于模65536的数域,即每一步运算都要对65536取模
输入输出描述
输入:输入n,表示n个测试用例,随后紧跟着n行表达式。
输出:每行输出对应案例表达式运算的结果,如遇到除以0的算数错误,请输出ArithmeticException。
Sample Input
2
2!!
3/2^4^4
Sample Output
2
ArithmeticException
#解析 :
解析&&细节,见以下注释
AC代码 - - -
#solution1
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod = 65536,p[65536];
int len,i;
char a[100+5];
inline int ini(){
int x=0,f=1;
char c=getchar();
while(c<48||c>57){
if(c==-1) return -1;
c=getchar();
}
while(c>=48&&c<=57){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void ins() {
len = i = 0;
char c = getchar();
while(!(c>=48&&c<=57||c=='-'||c=='+'||c=='/'||c=='*'||c=='^'||c=='!')) c=getchar();
while(c>=48&&c<=57||c=='-'||c=='+'||c=='/'||c=='*'||c=='^'||c=='!') {
a[len++] = c;
c = getchar();
}
}
ll getsnum() {
ll x = 0;
while(i<len&&a[i]>=48&&a[i]<=57) {
x = (x<<3)+(x<<1)+(a[i]^48);
x %= mod;
++i;
}
return x;
}
ll kp(ll b,ll k) {
ll res = 1;
while(k) {
if(k%2==1) {
res = res*b%mod;
}
b = b*b%mod;
k /= 2;
}
return res;
}
int main() {
int T = ini();
p[0]=1;
for(int j = 1; j < mod; ++j) p[j] = p[j-1]*j%mod;
if(T<0) return 0;
while(T--) {
ins();
ll res = 0, f = 1, pre = 0, ch = 0;
bool flag = true, anwserf = true;
while(i<len) {
if(a[i]=='-') f = -1;
if(a[i]=='-'||a[i]=='+') ++i;
while(i<len&&a[i]!='-'&&a[i]!='+') {//I.以加好为分割点
if(!(a[i]>=48&&a[i]<=57)) ch = a[i++];//II.以*或/为分割点
ll ans = getsnum();
while(i<len&&a[i]=='!') {//难点1,阶乘后面有^,例4!!!^2^2
ans = p[ans];
++i;
}
while(i<len&&a[i]=='^') {//III.以^作为分割点,根据最高优先级,我们可以把类似n!看成一个整体
++i;
ll x1 = getsnum();
while(i<len&&a[i]=='!') {//难点2,^后面的数字n!,例3!!^7!^3^4!!^7
x1 = p[x1];//难点3,阶乘需要打表即可,一个最多只有mod个,一个一个求会超时
++i;
}
ans = kp(ans,x1);
}
if(flag) {
pre=ans;
flag = false;
}else {
if(ch=='*') {
pre = pre*ans%mod;
}else {
if(ans==0) {
i=len;
anwserf = false;
break;
}else {
pre /= ans;
}
}
}
}
res = (res+f*pre)%mod;
pre = 0;
f = 1;
flag = true;
}
if(anwserf) printf("%lld\n",res);
else printf("ArithmeticException\n");
}
return 0;
}