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.
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;
}