• HDU 5920 Ugly Problem


    说起这道题, 真是一把辛酸泪.

    题意

    将一个正整数 $n(le 10^{1000})$ 分解成不超过50个回文数的和.

    做法

    构造.
    队友UHC提出的一种构造方法, 写起来比较方便一些, 而且比较巧妙. 可惜我码力太弱, 现场没调出来.
    大体的想法是:
    将一个数"等"分成两半. 如果长度为奇数可以采取下面两种处理方法之一.

    1. 在开头补0.
    2. 后一半 (低位) 的长度向下取整.

    我采取第2种处理方式.

    设前一半的长度为$h_1$, 后一半的长度为 $h_2$.
    然后将前一半长

    (写不下去了..., 贴代码...)

    Implementation

    #include <bits/stdc++.h>
    using namespace std;
    
    using num=vector<int>;
    using iter=num::iterator;
    using riter=num::reverse_iterator;
    
    
    bool Less(const num &a, const num &b){  // a and b are of same length
        for(auto it1=a.rbegin(), it2=b.rbegin(); it1!=a.rend(); ++it1, ++it2)
            if(*it1 != *it2){
                return *it1 < *it2;
            }
        return false;
    }
    
    void borrow(num &a){
            for(int i=a.size()/2; i<a.size(); i++)
                if(a[i]){
                    for(--a[i]; i; a[--i]+=9);  //?
                    break;
                }
            while(a.size() && *a.rbegin()==0)
                a.pop_back();
    }
    
    void split(num &lo, num &hi, const num &a){
        auto mid=a.begin()+a.size()/2;
        lo={a.begin(), mid};
        hi={mid, a.end()};
    }
    
    num operator-(num a, num b){    // a and b are of same length && a >= b
        num res;
        for(int i=0; i<a.size(); i++){
            if(a[i]<b[i]){
                a[i]+=10;
                a[i+1]-=1;
            }
            res.push_back(a[i]-b[i]);
        }
    
        for(; res.size() && *res.rbegin()==0; )
            res.pop_back();
    
        if(res.size()){ //error-prone
            for(int i=0; i<res.size()-1; i++){
                res[i+1]+=res[i]/10;
                res[i]%=10;
            }
    
            for(; *res.rbegin()>9; ){
                int t=*res.rbegin();
                *res.rbegin()%=10;
                res.push_back(t/10);
            }
        }
    
        for(auto x:res){
            assert(x>=0 && x<10);
        }
    
        return res;
    }
    
    vector<num> res;
    
    void out(const num &a){
        for(auto it=a.rbegin(); it!=a.rend(); ++it)
            cout<<*it;
        cout<<endl;
    }
    
    void solve(num &a){
        res.clear();
        num lo, hi;
        int ones=0;
    
        while(a.size()>1){
            // out(a);
            split(lo, hi, a);
            num rhi(hi.rbegin(), hi.rbegin()+lo.size());
            if(Less(lo, rhi)){
                borrow(a);
                ++ones;
                continue;
            }
            a=lo-rhi;
            // There is no advantage to using {} initialization, and one trap,
            // when using auto to get the type determined by the initializer.
            // The trap is that if the initializer is a {}-list, we may not want its
            // type deduced.
            //initializer_list<num> xx={rhi};
            //cout<<typeid(xx).name()<<endl;
            auto tmp=rhi;
            //cout<<typeid(tmp).name()<<endl;
            for(auto &x: hi)
                tmp.push_back(x);
            res.push_back(tmp);
        }
    
        if(a.size()) res.push_back(a);
    
        assert(res.size() + ones <= 50);
    
        printf("%d
    ", res.size()+ones);
        for(auto &x: res)
            out(x);
        while(ones--)
            puts("1");
    }
    
    char s[1<<10];
    
    int main(){
    
        // num x, y;
        // in g++:
        // direct-list-intialization of 'auto' requires exactly one element
        // for deduction to 'std::initializer_list', use copy-list-intialization (i.e. add '=' before the '{')
        // auto xx{x, y};
    
        int T, cas=0;
        num a;
        for(cin>>T; T--; ){
            scanf("%s", s);
            a.clear();
            int n=strlen(s);
            for(int i=n-1; i>=0; --i)
                a.push_back(s[i]-'0');
            printf("Case #%d:
    ", ++cas);
            solve(a);
        }
        return 0;
    }
    
  • 相关阅读:
    《JavaScript》forEach()和map()
    《JavaScript》split和join
    09慕课网《进击Node.js基础(一)》HTTP-get/request
    08慕课网《进击Node.js基础(一)》事件events
    07慕课网《进击Node.js基础(一)》HTTP小爬虫
    06慕课网《进击Node.js基础(一)》作用域和上下文
    05慕课网《进击Node.js基础(一)》HTTP概念进阶(同步/异步)
    前端每周学习分享--第4期
    前端每周学习分享--第3期
    前端每周学习分享--第2期
  • 原文地址:https://www.cnblogs.com/Patt/p/5969973.html
Copyright © 2020-2023  润新知