原题链接https://ac.nowcoder.com/acm/contest/5674/A


题目描述

某日,土拨鼠(Groundhog)在数学课上得知:任何正整数可以变成2的幂的形式
以上为废话。
输入表达式(字符串),并把字符串转化为原10进制形式。


输入描述

输入一行字符串,作为2的幂的形式,其中括号内的数或式为指数。

输出描述

输出一个整数作为结果。

数据范围

字符串长度不超过20000,原整数大小在 的范围内。


样例

  • 输入

    2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
  • 输出

    1315

题解思路

首先看数据范围可以猜到是应该是高精度(怪哉,本场有好几道高精)
由于在输入中有括号出现,所以可以猜想用括号匹配。
又因为输入都与2相关,所以可以在搜索到2时,在判断下一个字符是否为')':若是,则递归到下一层;若否,则直接在本层加2。
由于本题是高精度,所以单纯的用快速幂是不行的,要再加上高精下的快速幂。


参考代码

#include<bits/stdc++.h>
using namespace std;
char s[20010];
long long sum;
int ans[205],len;
void hp(int b[],int lenn)//高精处理
{
    len=max(len,lenn);
    for(int i=1;i<=len;++i)
    {
        ans[i]+=b[i];
        ans[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    while(ans[len+1])++len;
}
int b[1005];
void ksm(long long c)//高精快速幂,同时也处理了高精度
{
    memset(b,0,sizeof(b));
    b[1]=1;
    int k=1;
    for(int i=1;i<=c;++i)
    {
        int 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;
        }
    }
    hp(b,k);
}
long long ksm1(long long b,long long c)//普通快速幂,用于计算通常情况下的2的幂运算
{
    long long d=1;
    while(c>0)
    {
        if(c&1)d*=b;
        c>>=1;
        b*=b;
    }
    return d;
}
int p,k;
long long dg(long long x,long long h)
{
    long long q=0;p=0;
    for(int i=x;i<k;i++)//搜索处理
    {
        p=max(p,i);
        if(s[i]=='(') h++;
        if(s[i]==')') h--;
        if(!h){ksm(q);return 0;}
        if(s[i]==')') return ksm1(2,q);
        if(s[i]=='2')
        {
            if(s[i+1]=='(') q+=dg(i+1,h),i=p;
            else q+=2;
        }
    }
}
int main()
{
    scanf("%s",s);
    k=strlen(s);
    for(int i=0;i<k;i++)
        if(s[i]=='2')
        {
            if(s[i+1]!='(')
            {
                memset(b,0,sizeof(b));
                b[1]=2;
                hp(b,1);
            }
            else dg(i+1,0),i=p;
        }
    for(int i=len;i>=1;i--)
        printf("%d",ans[i]);
}