HDU 1009 FatMouse' Trade(水贪心)

FatMouse' Trade

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38892    Accepted Submission(s): 12837

Problem Description

FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.
 

Input

The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.
 

Output

For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.
 

Sample Input

  
  
5 3 7 2 4 3 5 2 20 3 25 18 24 15 15 10 -1 -1

 

Sample Output

13.333
31.500

So。。

这是一道简单的贪心,根据兑换比率排下序,然后再从比率高的开始算。不过原题真的很考验英语水准。大体意思如下:

题目描述:
有N个房间,你有M镑的猫粮,在第i个房间你最多可以花费F[i]的猫粮来交换J[i]的豆子,交换可以按比例来,不一定全部交换,能在多个房间交换。求M镑最多能交换多少豆子。

输入描述:
输入数据有多组,每行有两个整数M和N,接下有N行,每行有两个整数J[i]和F[i]。当M=-1和N=-1时结束。所有整数不会大于1000。

输出描述:
输出能换得的最大豆子数,保留三位小数。

  排序我用的qsort,因为数据不大,也可以用一般的排序方法,比如选择,冒泡等。开始的时候用的数组,有点麻烦,因为把比率排序后还要查找出来原来对应的房间,这是代码:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int cmp(const void *a,const void *b)
{
    return *(double *)a>*(double *)b?1:-1;
}
int main()
{
    int n,m,i,j;
    double s,a[1000],b[1000],c[1000],d[1000];    //c[],d[]为比率,一个排序(c[]),一个查找(d[])
    while(scanf("%d %d",&m,&n)&&!(m==-1&&n==-1))
    {
        s=0;
        for(i=0; i<n; i++)
        {
            scanf("%lf %lf",&a[i],&b[i]);
            c[i]=a[i]/b[i];
            d[i]=c[i];
        }
        qsort(c,n,sizeof(c[0]),cmp);
        for(i=n-1; i>=0; i--)       //排序时是按从小到大排的,所以从后往前找
        {
            for(j=0; j<n; j++)      //c[]是排好的,d[]和a[],b[]的顺序相同
                if(d[j]==c[i])
                {
                    d[j]=-1;        //若两个以上分母为零,则两个以上无穷大,要在找到一个后把这个消去
                    break;          //此时的j是找到的对应的a[],b[]的序号
                }
            if(m>=b[j])
            {
                s+=a[j];
                m-=b[j];
                continue;
            }
            s+=m*(a[j]/b[j]);
            break;
        }
        printf("%.3lf\n",s);
    }
    return 0;
}

 

 

后来又用结构体做了一遍,思路和前面一样,只是省去了排序后还要查找的过程

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
struct trade
{
    double a;
    double b;
    double c;
};
int cmp(const void *a,const void *b)
{
    return (*(trade *)a).c<(*(trade *)b).c?1:-1;
}
int main()
{
    int n,m,i;
    trade t[1000];
    double s;
    while(scanf("%d %d",&m,&n)&&!(m==-1&&n==-1))
    {
        s=0;
        for(i=0; i<n; i++)
        {
            scanf("%lf %lf",&t[i].a,&t[i].b);
            t[i].c=t[i].a/t[i].b;
        }
        qsort(t,n,sizeof(t[0]),cmp);
        for(i=0; i<n; i++)
        {
            if(m>=t[i].b)
            {
                s+=t[i].a;
                m-=t[i].b;
                continue;
            }
            s+=m*(t[i].a/t[i].b);
            break;
        }
        printf("%.3lf\n",s);
    }
    return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值