Four Operations HDU - 5938 貪心+模擬

題目鏈接
題意:給定一個全是數字(只包含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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章