Groundhog and 2-Power Representation

题意:给出一串字符串,2(x)表示2^x,问这串字符串表示的数是多少

因为我不太擅长字符串的题目,所以比赛的时候扔给队友做了,我A了两道签到就跑了,没想到队友后面好像鸽了。

看别人的代码,emmm,只有一个感想:python天下第一
对比下最短代码长度
python:
在这里插入图片描述
c++:
在这里插入图片描述
但无奈懒人只会c++。

好吧,回归正题吧,讲讲做法吧。首先是括号的问题,我们需要层层递归,直到括号里没有括号的情况,然后在从里往外算出次幂即可,答案最大范围为1e18,在2200-2300之间,所以我们只需要在最外面一层求高精度的幂即可(不会高精快速幂233),大括号里面的用普通快速幂解决。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>

typedef long long ll;

using namespace std;
char str[20010];
long long sum;
int ans[205], len, str_len = 1, rem, b[1005];

void up(int b[], int b_len) {//高精加
	len = max(len, b_len);
	for (int i = 1; i <= len; i++) {
		ans[i] += b[i];
		ans[i + 1] += ans[i] / 10;
		ans[i] = ans[i] % 10;
	}
	while (ans[len + 1]) len++;
}


ll quick_pow(ll a, ll b) {//快速幂
	ll ans = 1;
	while (b) {
		if (b & 1) ans = (ans * a);
		a = a * a;
		b /= 2;
	}
	return ans;
}

void quick_gj(ll p) {//高精的幂
	memset(b, 0, sizeof(b));
	b[1] = 1;
	int k = 1;
	for (int i = 1; i <= p; 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;
		}
	}
	up(b, k);
}

ll dfs(int top, int ret) {
	ll p = 0;
	rem = 0;
	for (int x = top; x < str_len; x++) {
		rem = max(x, rem);//记录遍历过的最右端
		if (str[x] == '(') ret++;
		if (str[x] == ')') ret--;
		if (!ret) {//最外层括号
			quick_gj(p);
			return 0;
		}
		if (str[x] == ')') return quick_pow(2ll, p);//内层括号
		if (str[x] == '2') {
			if (str[x + 1] == '(') p += dfs(x + 1, ret), x = rem;
			else p += 2;
		}
	}
}

int main() {
	scanf("%s", str);
	str_len = strlen(str);
	for (int top = 0; top < str_len; top++) {
		if (str[top] == '2') {
			if (str[top + 1] == '(') {
				dfs(top + 1, 0);
				top = rem;
			}
			else {
				memset(b, 0, sizeof(b));
				b[1] = 2;
				up(b, 1);
			}
		}
	}
	for (int i = len; i >= 1; i--) {
		printf("%d", ans[i]);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值