专栏文章

题解:CF2093B Expensive Number

CF2093B题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipk3xzw
此快照首次捕获于
2025/12/03 13:18
3 个月前
此快照最后确认于
2025/12/03 13:18
3 个月前
查看原文

简要题意

定义一个数 n=a1a2akn=\overline{a_1a_2\cdots a_k} 的花费为 a1a2aka1+a2++ak\frac{\overline{a_1a_2\cdots a_k}}{a_1+a_2+\cdots+a_k}。对其进行若干次操作,每次操作删除其中一位数,求使其花费最小的最少操作数。最多删除 k1k-1 个数位且最后得到的数必须大于 00

思路

当只有一个非 00 数位,即 n=a>0n=\overline{a} >0 时,花费为 aa=1\frac{a}{a}=1,容易证得此为最小花费。因此对于所有数,最小花费一定为 11。我们只需要在此基础上保留不影响该花费的数位,以最小化操作数。
我们选取最后一个非零数位 aenda_{end} 为分界点,对两边的数进行分类讨论:
  • i<endi < end 时,若 aia_i 不为 00,保留后花费必然增加,所以必须删除。在删除所有不为 00 的数后,所有前面的 00 变为前导零,并不会增加花费,不必删除。
  • i>endi>end 时,所有数都是 00,每有一个 00 就会使分子变大,而分母不变,因此也必须删除。
综上,我们删除 aenda_{end} 前所有不为 00 的数位,删除 aenda_{end} 后所有的数位。
CPP
#include <bits/stdc++.h>
using namespace std;
int t;
string s;
int main()
{
    cin >>t;
    while (t--)
    {
        cin >> s;
        int cnt = 0, end = s.length() - 1;
        for (int i = s.length() - 1; i >= 0; i--)
        {
            if (s[i] != '0') {end=i;break;}
        }
        for (int i = 0; i < s.length(); i++)
        {
            if (i==end) continue;
            if (s[i] != '0' && i < end) cnt++;
            if (s[i] == '0' && i > end) cnt++;
        }
        cout << cnt << endl;
    }
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...