硬件DIY秀
总提交 : 229 测试通过 : 34
比赛描述
近期,计算机学院举办第四届学生课外科技节活动,硬件DIY秀活动使同学们组装电脑提高动手能力,主办方计算机学院分团委和科协决定购买电脑组件,每种类型的组件各需购买一个,并希望组装后的电脑能够实际使用。你的任务是帮助主办方最终确定购买何种性能组件,在最大限度地提高最低组件的性能,同时不能超过他们的预算。这里假设电脑的性能等同于其最薄弱组件的性能。
输入
第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括:
l 一行,含两个整数n,b:1≤n≤1000,表示组件的数目,1≤b≤1000000000,表示他们的预算。
l n行,按以下格式:“type name price quality”,type是一个字符串,表示组件的类型;name是一个字符串,表示组件的名称;price是一个整数(0≤price≤1000 000),表示组件的价格;quality是一个整数(0≤quality≤1000000000),表示组件的性能(越高越好)。字符串只能由字母和数字组成,最大长度为20个字符。
通常能够根据他们的预算来组装一台电脑。
输出
对于每个测试用例,输出包括:
l 一行,为一个整数:表示可能的最高性能。
样例输入
1
18 800
processor 3500_MHz 66 5
processor 4200_MHz 103 7
processor 5000_MHz 156 9
processor 6000_MHz 219 12
memory 1_GB 35 3
memory 2_GB 88 6
memory 4_GB 170 12
mainbord all_onboard 52 10
harddisk 250_GB 54 10
harddisk 500_FB 99 12
casing midi 36 10
monitor 17_inch 157 5
monitor 19_inch 175 7
monitor 20_inch 210 9
monitor 22_inch 293 12
mouse cordless_optical 18 12
mouse microsoft 30 9
keyboard office 4 10
样例输出
9
题目来源
南京邮电大学计算机学院首届ACM程序设计大赛(2009)
#include<iostream>
#include<algorithm>
#include<set>
#include<cstring>
using namespace std;
struct node1
{
char s[25];
long pri,qua;
int kind;
}a[1010];
struct comp1{ //比较累,按照质量升序排序,质量相同的话按照价格降序排序
bool operator()(const node1 &x,const node1 &y) const{
if(x.qua==y.qua){
return x.pri>y.pri;
}
return x.qua<y.qua;
}
};
bool comp(const node1 &x,const node1 &y){
if(!strcmp(x.s,y.s)){
return x.pri<y.pri; //名字相同,价格低的排在前面
}else{
return strcmp(x.s,y.s)<0; //字典序
}
}
int main(){
freopen("test.txt","r",stdin);
int c,n,b;
scanf("%d",&c);
while(c--){
scanf("%d%d",&n,&b);
getchar();
int i;
for(i=0;i<n;i++){
scanf("%s%*s%d%d",&a[i].s,&a[i].pri,&a[i].qua);
}
sort(a,a+n,comp); //按照种类名称排序,名称相同的话,按照价格从低到高排序
i=0;
int num=-1;
int beg[1010],end[1010];
while(i<n){ //给每个组件加上种类编号
num++; //种类从0开始编号
beg[num]=i; //beg[num]:种类编号为num的 最小ID
a[i].kind=num;
while(!strcmp(a[i].s,a[i+1].s))
{
i++;
a[i].kind=num;
}
i++;
end[num]=i; //beg[num]:种类编号为num的 最大ID+1
}
a[n].kind=-1;
multiset<node1,comp1>s; // ?
s.clear();
num++; //共有num个编号, 0……n-1
int b_temp=0;
for(i=0;i<num;i++){
s.insert(a[beg[i]]); // s 中存放每种编号的 最小ID 的节点
b_temp+=a[beg[i]].pri; // b_temp 每种组件的最低价的和
beg[i]++; // z最小标号考虑完之后就不在考虑
}
int ans;
while(1)
{
int x=(*s.begin()).kind;//set中质量最低的种类编号
ans=(*s.begin()).qua; //set中质量最低的种类的 质量
while((beg[x]<end[x])&&((*s.begin()).qua>=a[beg[x]].qua)){
beg[x]++; //找到同种类中质量稍微好一点的一个
}
if(beg[x]==end[x]){ //没有更好的质量了,就不找了,整体最优就是ans了
break;
}
b_temp-=(*s.begin()).pri;
s.erase(s.begin());
b_temp+=a[beg[x]].pri; //替换成更高质量的
if(b_temp>b) break; //花费超支的话就不谈了
node1 temp;
temp.kind=x;
temp.pri=a[beg[x]].pri;
temp.qua=a[beg[x]].qua;
s.insert(temp);
beg[x]++;
}
printf("%d\n",ans);
}
return 0;
}