题意:先给你一个数字T表示有T组数据,然后给你N,B,下面有N个配件,你有B元钱,下面N行表示N个物品,每个物品有四个属性:类型,名字,价格,质量,你要配出来一台尽可能好的computer,一台computer的好坏是由它质量最坏的配件决定的,要求每种类型的配件都至少有一个。
思路:典型的最小值最大化的题目,所以我们直接二分这个答案就好了。难就难在输入数据的处理,这里我采取的方法是使用map把每个类型映射成一个数字,然后这些数字作为vector的下标,同类型的存在同一个vector下,然后这样就可以了。但是要注意每组数据结束要清空map和vector,还有就是cin会超时!!!
(HDU2333 || uva12124 || poj3497 || zoj3090)
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3 + 5;
int N,B,kinds;
struct Goods
{
string type,name;//类型,名字
int price,quality;//价格,质量
};
map<string,int> M;
vector <Goods> goods[MAXN];
bool check(int q)
{
long long sum = 0;//统计花费
for(int i = 0; i < kinds; i++)//kinds类物品
{
int Min_price = INF;//该类物品中质量大于等于q的最低价格
for(int j = 0; j < goods[i].size(); j++)
{
if(goods[i][j].quality >= q)//质量大于等于q
{
Min_price = min(Min_price, goods[i][j].price);
}
}
sum += Min_price;
}
return sum <= B;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
kinds = 0;
scanf("%d%d",&N,&B);
int Min_quality = INF, Max_quality = -INF; //答案的最小值和最大值
for(int i = 0; i < N; i++)
{
Goods t;
cin >> t.type >> t.name;
//cin >> t.price >> t.quality;超时!!!
scanf("%d%d",&t.price, &t.quality);
if(M.count(t.type) == 0)//该种类没有出现过
{
M.insert(make_pair(t.type,kinds));//该种类插入map
kinds++;
}
goods[M[t.type]].push_back(t);//该物品对应种类编号插入容器
Min_quality = min(Min_quality, t.quality);
Max_quality = max(Max_quality, t.quality);
}
int ans = -1;//存储答案
int l = Min_quality, r = Max_quality, m = l + (r - l) / 2;//二分答案
while(l <= r)
{
if(check(m))
{
ans = m;
l = m + 1;
}
else r = m - 1;
m = l + (r - l) / 2;
}
printf("%d\n",ans);
M.clear();//每组数据清空map
for(int i = 0; i < kinds; i++) goods[i].clear();//每组数据清空vector
}
return 0;
}