题目链接
题意:给定一个全是数字(只包含1-9)的字符串(长度5到20),按照顺序插入±*/四个运算符,求最大的计算结果。有T组询问(1<=t<=100000)。
如果直接暴力会超时,在长度为20的字符串中有顺序插入4个运算符,20 * 19 * 18 * 17
种情况,约为204种情况。
分析得到计算的形式总是a + b - c * d / e
,要获取最大的结果,就要使a b e
尽可能大,c d
尽可能小,所以a b
中有一个是一位,有一个是多位;c d
都是一位,e
可能是一位可能是二位。
因为c d
是一位,c * d
的值1 - 81,当cd的积是一位数,我们除以一个一位数能得到最优;cd的积是2位数,除以一个两位数能得到最优。
ab中有一个是一位,一个是剩余位,有两种情况。
e一位或者两位,有两种情况。
我们分别找出在字符串相应的位置,计算4中情况,衡量最优答案。
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 20 + 5;
char s[MAXN];
// 返回字符对应的数字
ll change(int i)
{
return (s[i] - '0');
}
// 返回对应序列的数字
ll get(int p1, int p2)
{
ll result = 0, k = 1;
// 从高位倒序模拟
for (int i = p2; i >= p1; --i)
{
result += change(i) * k;
k *= 10;
}
return result;
}
// 返回longlong类型的较大值
ll max_(ll a, ll b)
{
return a > b ? a : b;
}
int main()
{
int n;
scanf("%d", &n);
int cnt = 0;
while (n--)
{
scanf("%s", s);
int len = strlen(s);
ll t1 = change(0) + get(1, len-4) - change(len-3) * change(len-2) / change(len-1);
ll t2 = change(len-4) + get(0, len-5) - change(len-3) * change(len-2) / change(len-1);
ll ans = max_(t1, t2);
// 注意只有当字符串长度大于5时,才需要考虑e是否是两位。长度为5的字符串只能刚好插入4个符号。
if (len > 5)
{
t1 = change(0) + get(1, len-5) - change(len-4) * change(len-3) / get(len-2, len-1);
t2 = change(len-5) + get(0, len-6) - change(len-4) * change(len-3) / get(len-2, len-1);
ans = max_(ans, max_(t1, t2));
}
printf("Case #%d: %lld\n", ++cnt, ans);
}
return 0;
}