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;
    }
    
  • 相关阅读:
    javascript如何实现图片隐藏?
    TypeScript数字分隔符和更严格的类属性检查
    JS 原生闭包模块化开发总结
    详解浏览器储存
    对象扩展运算符和 rest 运算符及 keyof 和查找类型
    Js实现动态轮播图效果
    javascript选择器有哪些?
    javascript的事件流模型都有什么?
    理解JavaScript中的语法和代码结构
    14. Cantor表
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12944560.html
Copyright © 2011-2022 走看看