UVA ~ 12124 ~ Assemble(map+二分)

题意:先给你一个数字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;  
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值