题目描述:有一批订单(order),需要n种设备组成一个交流系统。每种设备有m个设备制造商,每个设备制造商的设备都有不同的带宽(bandwidth)和价格(price)。
定义系统的带宽(B)为这个n个设备里面的最小带宽
定义系统的价格(P)为n个设备的总价格
现在要求你设计程序计算从设备制造商提供的所有设备中选出n个(每种一个)使得系统的B/P最大
输入格式:第一行一个整数t,表示总共有t组数据。以下每组数据第一行一个整数n,表示设备的种类,以下n行每行开头一个整数m(i)表示第i种类的设备制造商的数量。 m(i)后面接着m(i)对整数,每对整数表示这m(i)个设备的带宽和价格。
输出格式:每组数据输出一行一个小数,表示最大的B/P
数据约定:1<=n,m<=100
解题思路:贪心枚举
将所有设备以价格为关键字从小到大排序。然后依次枚举每个设备i,把当前设备i 的带宽当做系统的最小带宽,计算B/P,取所有B/P中的最大值。。这里可以加上一些优化。。
妈蛋的WA了7次。。因为快排写萎了。。。郁闷到死!!!
更详细的看代码注释。PS:第一次写代码注释。。。
#include <cstdio>
struct _dev{
int price;
int bandwith;
};
void sort(_dev *head, _dev *tail);
int main(int argc, char const *argv[])
{
int t;
scanf("%d", &t);
while(t--){
int n, m[111];
scanf("%d", &n);
_dev dev[111][111];
for(int i=0; i<n; ++i){
scanf("%d", m+i);
for(int j=0; j<m[i]; ++j){
scanf("%d%d", &dev[i][j].bandwith, &dev[i][j].price);
}
sort(dev[i],dev[i]+m[i]-1);
}
double ans=0;
for(int i=0; i<n; ++i){
for(int j=0; j<m[i]; ++j){ //两重循环保证每一个设备都被枚举到
//以当前设备的带宽为最小带宽,初始化此次系统构成方案
int minbandwith=dev[i][j].bandwith;
int sumprice=dev[i][j].price, k, r;
for(k=0; k<n; ++k){
if(k==i) { continue; } //当前设备所在的种类直接不考虑
for(r=0; r<m[k]; ++r){
//判断设备的带宽是否满足要求,满足要求,则选择这个设备,
//因为按照价格排了顺序,所以第一个满足要求的设备价格一定最小,
if(minbandwith<=dev[k][r].bandwith) {
sumprice += dev[k][r].price;
break;
}
}
//如果第k中设备里找不到符合要求的设备
//说明当前带宽的系统无法被构成,跳过该方案
if(r==m[k]){ break; }
}
//判断设备数量是否达到要求,数量不够,说明系统无法构成
if(k<n) { continue; }
//数量达到要求,更新结果。
if(minbandwith/(double)sumprice>ans) {
ans=minbandwith/(double)sumprice;
}
}
}
printf("%.3f\n", ans);
}
return 0;
}
void swap(_dev *a, _dev *b)
{
int tmpbandwith=a->bandwith;
a->bandwith=b->bandwith;
b->bandwith=tmpbandwith;
int tmpprice=a->price;
a->price=b->price;
b->price=tmpprice;
}
void sort(_dev *head, _dev *tail)
{
_dev *left=head, *right=tail;
int midprice=(head+(tail-head)/2)->price;
while(left<right){
while(left->price<midprice) { ++left; }
while(right->price>midprice) { --right; }
if(left<=right){ swap(left++,right--); }
}
if(left<tail) { sort(left, tail); }
if(right>head) { sort(head, right); }
}