zoukankan      html  css  js  c++  java
  • Codeforces 1181B Split a Number (贪心)

    题目链接

    题目大意

      把一个数划分成两个没有前导0的正整数,使其和最小。

    解题思路

      如果不考虑划出来的数有没有前导0的话很好做,为了使划出来的两个数尽量小,一定是要从中间划分的。这里需要注意长度为奇数的时候有两种划法,比如93123,可以化成931+23和93+123。
      那么如果从中间划会划出含有前导0的数呢?这样的话中间必定有一串连续的0,我们不能让这些0分开,所以就有了四种划法。设l为距离中间最近的左边的非0的数,r为右边最近的非0的数,那么就可以以l-1, l,r-1,r四个点为分割点(假设分割点划到第一个数里)划分(如果l==r相当于2个划分点)以得到位数最小的答案,然后取最小的答案即可。

    代码

    string num, s1, s2, ans;
    vector<string> ve; int n;
    void solve(int cut) {
        if (cut<0||cut+1>=n) return;
        s1 = num.substr(0, cut+1); 
        s2 = num.substr(cut+1, n-cut);
        if (s2.size()>1&&s2[0]=='0') return; 
        reverse(s1.begin(),s1.end());
        reverse(s2.begin(),s2.end());
        int l1 = 0, l2 = 0, carry = 0;
        while(l1<s1.size()||l2<s2.size()) {
            carry += l1<s1.size() ? s1[l1++]-'0' : 0;
            carry += l2<s2.size() ? s2[l2++]-'0' : 0;
            ans += carry%10+'0';
            carry /= 10;
        }
        if (carry) ans += carry+'0';
        reverse(ans.begin(),ans.end());
        ve.push_back(ans); ans.clear();
    }
    int main() {
        cin >> n >> num;
        int l = n/2, r = n/2;
        while(num[l]=='0') --l;
        while(r<n&&num[r]=='0') ++r;
        solve(l); solve(l-1);
        solve(r-1); solve(r);
        sort(ve.begin(),ve.end(),[](string a, string b) {
            return a.size()==b.size() ? a<b : a.size()<b.size();
        });
        cout << ve[0] << endl;
        return 0;
    }
    
  • 相关阅读:
    CSS定位
    使用开源框架进行get,post提交
    使用httpclient框架分别用post,get方式提交
    C++ const_cast
    C++ 类继承 常量对象调用函数
    C++ 类继承 子类调用父类
    C++ explicit关键字
    C++ class入门
    C#检测耗时操作
    面向对象编程入门
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12944560.html
Copyright © 2011-2022 走看看