Codeforces 792C 模拟

版权声明:欢迎转载,不要求署名~~~ https://blog.csdn.net/shadandeajian/article/details/81986363

传送门: 题目

题意:

给一个数字,你可以删除字符串某一个位置的字符,使其满足下列条件:

  • 数字没有前导0
  • 数字能够被3整除

求操作次数的最小值。

题解:

我们知道,一个数字所有位上的数字相加,能够被3整除,那么这个数字就能被3整除,所以我们可以依靠这个条件判断条件2。如果除的时候有余数,那么只需要从原来数字中删除一位,这一位的mod恰好是余数,那么就可以满足条件。我们也可以删除两位,这两位每位的mod都是3-余数,相当于一种曲线救国的方法。因为是求3的倍数,所以只有这两种情况,可以用数学证明,因为本人数学比较菜,就不证明了,其实只要仔细想一想,就会觉得这么做是有道理的。

AC代码:

#include <bits/stdc++.h>
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
using namespace std;

int judge(string str) {//判断是否能被3整除
    int sum = 0;
    for (auto x : str)
        sum = (sum + x - '0') % 3;
    return sum | !str.size();
}
void removelead0(string& str) {//去掉前导0
    while ((*str.begin()) == '0' && str.size() > 1)
        str.erase(str.begin());
}
int main(void) {
    string str, str1, str2;
    cin >> str;
    int reminder = judge(str), reminder2 = 3 - reminder, t1 = 1, t2 = 2;
    str1 = str2 = str;
    for (int i = (int)str.size() - 1; i >= 0; i--) {
        if ((str[i] - '0') % 3 == reminder && t1)//去掉多余的那个数,然后就可以被32整除了
            str1.erase(i, 1), --t1;
        if ((str[i] - '0') % 3 == reminder2 && t2)//曲线救国
            str2.erase(i, 1), --t2;
    }
    t1 = judge(str1), t2 = judge(str2), removelead0(str1), removelead0(str2);
    if (t1 && t2)
        return 0 * puts("-1");
    if ((str1.size() > str2.size() && (!t1)) || t2)
        str2 = str1;
    cout << str2 << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81986363
今日推荐