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;
}
发布了92 篇原创文章 · 获赞 33 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/105004540