Problem E. Bet(2016 China-Final)【高精度除法】

source:题目链接

题意:这是2016 ACM-ICPC China-Final的E题,题意是赌博游戏,给出n个队的赔率,问你最多能下注多少个队,才能使得不论你下注的这些队中哪一个队赢了你都可以赚,也就是说回报的金钱大于下注的总额。

思路:先用数学翻译一下此题,其实很简单就可以推出一个不等式:用P-i代表我下注的总额中第i个队占的金额占比,应有:P-i > A-i/(A-i+B-i)

要使得尽可能下注多的队,就将所有队的A-i/(A-i+B-i)排序,挨着取,直到总和>1

思路很简单,但是此题的坑在于如果单纯地用double的话会爆精度!所以有必要用高精度除法!

由于A-i/(A-i+B-i)一定是0.几的小数,所以直接用个二维数组存小数点后的数即可,排序,再用个sum数组记录累加和,直到进位产生时结束!

涉及到高精度除法,一定要注意的一个问题:四舍五入!!!(不加四舍五入过不了)

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define M 999

int num[105][M+5],stand[105],sum[M+5];

void cal_div(int x,int y,int quo[M+5])  //高精度除法
{
    for(int i=0;i<=M;i++)
    {
        x*=10;
        quo[i]=x/y;
        x=x%y;
        if(x==0) break;
    }
    if(quo[M]>=5) quo[M-1]++;  //四舍五入!!!不加过不了!!
}

int cal_sum(int x[M+5],int y[M+5])  //高精度加法
{
    int c=0;
    for(int i=M-1;i>=0;i--)
    {
        x[i]=x[i]+y[i]+c;
        c=x[i]/10;
        x[i]=x[i]%10;
    }
    return c;
}

int cmp(const int x,const int y)  //sort排序比较标准
{
    int i=0;
    while(num[x][i]==num[y][i] && i<M) i++;
    return (num[x][i] < num[y][i]) ;
}

int main()
{
    int t,T,n,xa,xb,ans;
    double a,b;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        scanf("%d",&n);
        memset(num,0,sizeof(num));
        for(int i=0;i<n;i++)
        {
            scanf("%lf:%lf",&a,&b);
            xa=floor(a*1000+0.5);
            xb=floor(b*1000+0.5);
            cal_div(xa,xa+xb,num[i]);
        }
        for(int i=0;i<n;i++)
            stand[i]=i;
        sort(stand,stand+n,cmp);
        int flag=0;
        ans=0;
        memset(sum,0,sizeof(sum));
        while(flag==0 && ans<n)
        {
            flag=cal_sum(sum,num[stand[ans]]);
            if(flag==0) ans++;
        }
        if(t==1) printf("Case #%d: %d",t,ans);
        else printf("\nCase #%d: %d",t,ans);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值