zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x07 贪心 NOIP2012 vector模拟高精度计算

    题目链接:https://www.acwing.com/problem/content/description/116/

    证明转载于https://www.acwing.com/problem/content/description/116/

     

    使用“轻微扰动”的方法判断当前的选择是否是最优的,我们可以从中看到,减少逆序对的数量不会使结果更差,增加逆序对的数量不会使得结果更好,所以按照冒泡排序的思想,可以通过相邻项交换来使最大值最小。由于乘积可能达到1e4000,所以使用高精度进行处理。

    代码如下:

    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define maxn 1005
    struct node{
        int a,b;
        bool operator < (const node& other)const {
            return a*b<other.a*other.b;//按照贪心策略进行排序 
        }
    }p[maxn];
    vector<int> mul(vector<int> a,int b){//大整数存储在vector中,a*b 
        vector<int> c;
        int t=0;
        for(int i=0;i<a.size();i++){
            t+=a[i]*b;
            c.push_back(t%10);
            t/=10;//进位 
        }
        while(t){//将剩余进位压入vector 
            c.push_back(t%10);
            t/=10;
        } 
        return c;
    }
    vector<int> div(vector<int> a,int b){//大整数与一个int整数相除取整 
        vector<int> c;
        bool is_first=true;//除法的结果是从第一个有效位开始存储的 
        int t=0; 
        for(int i=a.size()-1;i>=0;i--){//模拟除法,从最高位开始计算 
            t=t*10+a[i];
            int x=t/b;
            if(!is_first || x){//第一个非零的数为有效位数,或者不是第一个数,都是有效位数 
                is_first=false;
                c.push_back(x);
            }
            t%=b;//余数参与下一轮计算 
        }
        reverse(c.begin(),c.end());//除数的计算中数字出现顺序是颠倒的 
        return c; 
    }
    vector<int> max_vec(vector<int> a,vector<int> b){//返回较大的大数 
        if(a.size()>b.size())return a;
        if(a.size()<b.size())return b;
    //    两个vector位数相同就从最高位开始逐个位数比较 
        if(vector<int>(a.rbegin(),a.rend()) > vector<int>(b.rbegin(),b.rend()))return a;
        return b;
    }
    int main (){
        int n;
        cin>>n;
        for(int i=0;i<=n;i++)scanf("%d%d",&p[i].a,&p[i].b);//最前面的国王也算一个 
        sort(p+1,p+n+1);
        vector<int> product(1,1);//累乘的基数,存放了一个1
        vector<int> res(1,0);//存放的是最大的金币数,也就是结果
        
        for(int i=0;i<=n;i++){
            if(i)res=max_vec(res,div(product,p[i].b));//前面A的前缀积除以b
            product=mul(product,p[i].a);
        }
        for(int i=res.size()-1;i>=0;i--)cout<<res[i];
        cout<<endl;
        return 0; 
    } 
  • 相关阅读:
    天梯赛5-12 愿天下有情人都是失散多年的兄妹 【dfs】
    poj2718 Smallest Difference【贪心】
    HDU problem 5635 LCP Array【思维】
    codeforces 782C Andryusha and Colored Balloons【构造】
    HDU 4278 Faulty Odometer【进制转换】
    codeforces B. The Meeting Place Cannot Be Changed【二分】
    POJ 3264 Balanced Lineup 【线段树】
    HDU 1850
    CodeForces-714C
    HDU Problem 1247 Hat's Words 【字典树】
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13139945.html
Copyright © 2011-2022 走看看