2020牛客暑期多校训练营(第九场) Groundhog and 2-Power Representation

原题
题目描述
输入计算式,求解。其中 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
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]);
}

你可能感兴趣的:(2020牛客暑期多校训练营(第九场) Groundhog and 2-Power Representation)