zoukankan      html  css  js  c++  java
  • 【高精度+贪心】【NOIP2012】国王游戏

    Description

    恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

     Input Description

    输入文件为game.in。

    第一行包含一个整数n,表示大臣的人数。 第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。 接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

    Output Description

     输出文件名为game.out。

    输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

     Data Size & Hint 

    对于20%的数据,有1≤ n≤ 10,0 < a、b < 8;对于40%的数据,有1≤ n≤20,0 < a、b < 8; 对于60%的数据,有1≤ n≤100;对于60%的数据,保证答案不超过10^9; 对于100%的数据,有1 ≤ n ≤1,000,0 < a、b < 10000。

    Solution

    贪心
    设(a1,b1),(a2,b2)是两个连续的大臣左右手的数。
    设Sum为a1前的左边数的积
    分两种情况:
    1在2前: ans1=sum/b1 ans2=sum*a1/b2
    2在1前: ans2=sum/b2 ans1=sum*a2/b1;
    先假设1在2前,我们讨论是否交换1和2的位置
    若ans1>ans2 (即 b2>a1b1) 显然交换后 ans1>ans2 故不交换;
    若ans1<ans2 则比较交换后 ans2与交换前ans1 的值
    (即比较a1b1与a2b2的大小关系)
    故若a1b1<a2b2 则不交换 否则交换
    证明完贪心之后 因为要相乘 积较大 所以要高精
    高精部分我参照了f_void的打法
    用的是重载定义符的方式写的 并且用到了压位

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    const int yh=1e4;
    int n;
    
    struct node
    {
        int l,r;
    }a[1005];
    
    struct bigNumber
    {
        int len,num[6000];
        bigNumber()
        {
            len=0;
            memset(num,0,sizeof num);
        }
    }ans,sum,tmp;
    
    bool cmp(node x,node y)
    {
        return(x.l*x.r<y.l*y.r);
    }
    
    int read()
    {
        int f=1,res=0;char c=getchar();
        while ('0'>c||c>'9') {if (c=='-') f=-1; c=getchar();}
        while ('0'<=c&&c<='9') {res=res*10+c-'0'; c=getchar();}
        return res*f;
    }
    
    bigNumber operator *(bigNumber x,int y)
    {
        int temp=0;
        for (int i=1;i<=x.len;i++)
        {
            temp+=x.num[i]*y;
            x.num[i]=temp%yh;
            temp=temp/yh;
        }
        if (temp>0) x.num[++x.len]=temp;
        return x;
    }
    
    bigNumber operator /(bigNumber x,int y)
    {
        int temp=0;
        for (int i=x.len;i>=1;i--)
        {
            temp=temp*yh+x.num[i];
            x.num[i]=temp/y;
            temp=temp%y;
        }
        while (!x.num[x.len]&&x.len>0) x.len--;
        return x;
    }
    
    bool operator < (bigNumber x,bigNumber y)
    {
        if (y.len>x.len) return 1;
        if (y.len<x.len) return 0;    
        for (int i=y.len;i>=1;i--)
        {
            if (x.num[i]<y.num[i]) return 1;
            else if (x.num[i]>y.num[i]) return 0;
        }
        return 0;
    }
    
    int main()
    {
        n=read();
        for (int i=0;i<=n;i++)
        {
            a[i].l=read();
            a[i].r=read();
        }
        std::sort(a+1,a+n+1,cmp);
        sum.num[++sum.len]=a[0].l;
        for (int i=1;i<=n;i++)
        {
            tmp=sum/a[i].r;
            if (ans<tmp)
            {
                for (int i=0;i<=tmp.len;i++)
                    ans.num[i]=tmp.num[i];
                ans.len=tmp.len;
            }
            sum=sum*a[i].l;
        }
        printf("%d",ans.num[ans.len]);
        for (int i=ans.len-1;i>=1;i--)
        {
            printf("%.4d",ans.num[i]);
        }
    }
  • 相关阅读:
    SQLServer提取日期中的年月日及其他格式
    大白话解说,半分钟就懂 --- 分布式与集群是什么 ? 区别是什么?
    VS2015 Git 源码管理工具简单入门
    Web.Config配置文件中customErrors元素的使用方法
    C#发起Http请求,调用接口
    如何停止和禁用Linux系统中的不需要的服务
    QtCreator调试传入运行参数
    gSOAP 在windows下的安装与使用(mingw32)
    MinGW 使用 mintty 终端替代默认终端以解决界面上复制与粘贴的问题
    在windows下执行./configure,make,makeinstall源码安装程序spice-gtk
  • 原文地址:https://www.cnblogs.com/Shawn7xc/p/7701250.html
Copyright © 2011-2022 走看看