CodeForces - 762B USB vs. PS2 ( 贪心 )

/*
  电脑有3种:只有 USB 接口、只有 PS/2 接口、两种接口都有的,数目分别为 a、b、c
  
  将2种鼠标分类后按价格排序,先处理只有一种接口的(只有一种接口的电脑,没有选择鼠标的余地,只能有什么接口用什么鼠标)
  
  再处理2种接口都有的鼠标,每次从当前剩下的鼠标中,贪心选取价格最小的,这样就能使得总费用最小
  
  最初,我自己用了一种比较复杂的写法...
  
  做完后搜题解,看到还有别的写法,特别巧妙地用了pair,于是自己也用这种方法又做了一次,也就是法二
*/


//法一
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#define Clear(x, y) memset(x, y, sizeof(x))
#define rep(i, k, n) for (int i = k; i < (n); i++)
using namespace std;
const int N = 3e5;
typedef long long LL;
string str;
LL va[N], vb[N]; //value of a / value of b
int main()
{
	int a, b, c, m, value;
	while (cin >> a >> b >> c)
	{
		Clear(va, 0);
		Clear(vb, 0);
		cin >> m;
		int suma = 0, sumb = 0;
		rep(i, 0, m)
		{
			cin >> value >> str;
			if (str == "USB") va[suma++] = value;
			else vb[sumb++] = value;
		}
		sort(va, va + suma);
		sort(vb, vb + sumb);
		int i = 0, j = 0, k = 0;
		LL num = 0, money = 0;
		while ( i < min(a, suma) )
		{
			money += va[i];
			num++; i++;
		}
		while ( j < min(b, sumb) )
		{
			money += vb[j];
			num++; j++;
		}
		while ( ( (i < suma) || (j < sumb) ) && (k < c) )
		{
			//如果某一种没了,则一定是取另外一种 
			if (i == suma)
			{
				money += vb[j++];
			}
			else if (j == sumb)
			{
				money += va[i++];
			}
			//如果两种都还有剩余,每次贪心选取当前可取范围中,价格最小的那个 
			else
			{
				if ( va[i] < vb[j] )
				{
					money += va[i]; i++;
				}
				else
				{
					money += vb[j]; j++;
				}
			}
			k++; num++;
		}
		cout << num << " " << money << endl;
	}
	return 0;
} 

//法二
#include <bits/stdc++.h>
#define rep(i, k, n) for (int i = k; i < n; i++) 
using namespace std;
typedef long long LL;
LL a, b, c, cnt, mon, m; //cnt为总数,mon为总金额
const int N = 5e5 + 5;
const string s1 = "USB";
const string s2 = "PS/2";
pair<long long, string> p[N];
int main()
{
	cin >> a >> b >> c >> m;
	rep(i, 0, m) cin >> p[i].first >> p[i].second;
	sort(p, p + m);
	rep(i, 0, m)
	{
		if (a && p[i].second == s1)
		{
			a--;
			cnt++;
			mon += p[i].first;
		}
		else if (b && p[i].second == s2)
		{
			b--;
			cnt++;
			mon += p[i].first;
		}
		else if (c)
		{
			c--;
			cnt++;
			mon += p[i].first;
		}
	}
	cout << cnt << " " << mon << endl;
} 

-----------------------------------------------------------------------------------------------

碎碎念:

忙里偷闲做道题,做完感觉连心情都变好了!~突然觉得,如果能每天先做一道题再做别的,会不会一整天都很开心,hhhhh

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值