航院1009: FatMouse’s Trade

航院1009 FatMouse’s Trade 解题报告

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

Input
The input consists of multipletest cases. Each test case begins with a line containing two non-negativeintegers M and N. Then N lines follow, each contains two non-negative integersJ[i] and F[i] respectively. The last test case is followed by two -1’s. Allintegers are not greater than 1000.

Output
For each test case, print in asingle line a real number accurate up to 3 decimal places, which is the maximumamount 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

解题思路:
1.先计算出每一个房间平均一单位猫粮可以交换多少豆子。
2.将平均一单位猫粮交换的豆子的数量由大到小进行排序。
3.当总猫粮数大于当前猫粮数时,累加这一房间的豆子,同时总猫粮数减去当前房间猫粮数。
4.当总猫粮数小于等于当前猫粮数时,用剩余猫粮数乘以此房间平均一单位猫粮可以交换的豆子。
5.输出豆子数。

错误原因:
代码1:
1. 未充分考虑各种情况。题目中说每个数据都是非负整数,未考虑M大于F[i]的和的情况。
2. 进行排序的时候,未将就j[i]和f[i]分别进行排序。

经验总结:
代码1:
1. 如果程序执行到固定某一步时结束,则可以使用完整循环,在需要结束时判断并跳出即可。
代码2:
1: 进行结构体排序时,循环要从0开始,而不能从1.
2: 希望由结构体中两个变量(相乘,相除……..)的结果进行排序,可以再设置一个变量作为两个变量的结果,排序时以此结果作为排序的参考值。
3: 想要将整形结果变为浮点型,只需乘以1.0。

正确程序代码1:

#include<stdio.h>
double j[1005]={0},f[1005]={0};
int main()
{
     int n, i, k;
     double m,t1, t2;
     double sum;
     while(scanf("%lf%d",&m, &n)!=EOF)
     {
           if(m==-1&& n==-1)
           {
                return0;
           }

           sum=0.0;
           for(i=1;i<=n;i++)
           {
                scanf("%lf%lf",&j[i], &f[i]);
           }

           for(i=1;i<=n-1;i++)
           {
                for(k=i+1;k<=n;k++)
                {
                     if(j[i]/f[i]<j[k]/f[k])
                     {
                          t1=j[i];
                          j[i]=j[k];
                          j[k]=t1;
                          t2=f[i];
                          f[i]=f[k];
                          f[k]=t2;
                     }
                }
           }
           for(i=1;i<=n;i++)
           {
                if(m>f[i])
                {
                     sum+=j[i];
                     m=m-f[i];
                }
                else
           {
                sum+=(double)m*j[i]/f[i];
                break;
           }
           }

            printf("%.3lf\n", sum);
     }
     return 0;
}

正确程序代码2(结构体排序):

#include<stdio.h>
#include<algorithm>
using namespace std;

struct trade
{
    int j;
    int f;
    double p;
};

double cmp(trade a, trade b)
{
    return a.p > b.p;
}

int main(void)
{
    struct trade fatmouse[1005];
    int m, n, i;
    double sum;
    while(scanf("%d%d", &m, &n))
    {
    sum = 0.0;
    if(m == - 1 && n ==-1)
    {
        break;
    }
    for(i = 0; i <= n - 1; i ++)
    {
        scanf("%d%d", &fatmouse[i].j, &fatmouse[i].f);
        fatmouse[i].p = 1.0 * fatmouse[i].j/fatmouse[i].f;
    }
    sort(fatmouse, fatmouse+n, cmp);

    for(i = 0; i <= n - 1; i ++)
    {
        if(m > fatmouse[i].f)
        {
            sum +=fatmouse[i].j;
            m -= fatmouse[i].f;
        }
        else
        {
            sum += (fatmouse[i].j * 1.0/fatmouse[i].f)*m;
            break;
        }
    }
    printf("%.3f\n", sum);
    }
    return 0;
}

转载于:https://www.cnblogs.com/moon13579/p/8652701.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值