題目鏈接
題意:給定一個全是數字(只包含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;
}