原题
题目描述
输入计算式,求解。其中
2
(
x
)
2(x)
2(x)表示
2
2
2 的
x
x
x 次方,式中每一项都对应着答案在二进制表示下的数位为
1
1
1的位。
样例1
输入
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输出
1315
样例2
输入
2(2(2)+2+2(0))+2(2+2(0))+2(0)
输出
137
思路
因为数字很大,所以要用高精度。用一个数字
h
h
h来统计括号有没有匹配完,用
p
p
p来统计当前计算的数字达到的字符串的位数。
若在字符串中找到了一个
′
2
′
:
'2':
′2′:
若下一个字符是
′
(
′
'('
′(′,则进行递归。
否则直接在答案上加上
2
2
2。
递归
:
:
:
若遇到左括号,
h
+
+
h++
h++。
若遇到右括号,
h
−
−
h--
h−−。
若
h
=
=
0
h==0
h==0,则表示这一串
2
2
2计算好了,快速幂计算答案并累加,退出递归。
更新最新计算的位数。
若遇到右括号
:
:
:
若下一个字符是
′
(
′
'('
′(′,则再次进行递归。
否则直接在指数上加上
2
2
2。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char a[20010];
ll sum;
int ans[205],b[1005],lens,p,k;
void jia(int b[],int len)//累加
{
lens=max(lens,len);
for(int i=1;i<=lens;i++)ans[i]+=b[i],ans[i+1]+=ans[i]/10,ans[i]%=10;
while(ans[lens+1])lens++;
}
void GJksm(ll c)//快速幂并累加
{
memset(b,0,sizeof(b));b[1]=1;int k=1;
for(int x=0,i=1;i<=c;i++,x=0)
for(int j=1;j<=k;j++)
{
b[j]=b[j]*2+x,x=b[j]/10,b[j]%=10;
if(x&&j==k) k++;
}
jia(b,k);
}
ll ksm(ll b,ll c) //快速幂算2的指数
{
ll d=1;
while(c>0)
{
if(c&1)d*=b;
c>>=1;
b*=b;
}
return d;
}
ll dg(ll x,ll h)//递归
{
ll q=0;p=0;
for(int i=x;i<k;i++,p=max(p,i))
{
if(a[i]=='(')h++;
if(a[i]==')')h--;
if(!h){GJksm(q);return 0;}
if(a[i]==')')return ksm(2,q);
if(a[i]=='2')
if(a[i+1]=='(')q+=dg(i+1,h),i=p;
else q+=2;
}
}
int main()
{
scanf("%s",a);k=strlen(a);
for(int i=0;i<k;i++)
if(a[i]=='2')
if(a[i+1]!='('){memset(b,0,sizeof(b));b[1]=2;jia(b,1);}
else dg(i+1,0),i=p;//更新位数
for(int i=lens;i>=1;i--)printf("%d",ans[i]);
}