题意:给出一串字符串,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]);
}
}