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; 
    } 
  • 相关阅读:
    Git 游离态的一次问题解决
    idea每次新建项目的默认路径
    springboot 整合 freemarker
    Linux 学习网站
    springtask 基本使用和 cron 表达式
    volatile 关键字 和 i++ 原子性
    python 自动补全
    nagios维护之常见问题
    nagios维护之添加监控
    windows下python文件与文件夹操作
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13139945.html
Copyright © 2011-2022 走看看