(打这么多场比赛下来,终于能写几个题了,还是在大佬的教导下,才有了思路,所以一比完就要记录下来,免得自己忘了,太菜了)
题目链接:传送门儿
题意:给出n个班级的属性,a,b(a表示改班级的人数,b表示该班级拥有的奶茶数),现规定每个人最多喝一杯奶茶,并且不能喝自己班级的奶茶,问最多多少个人喝到奶茶?
思路:对每一个班级找它当前能喝到的最多的奶茶数,无疑 tmp=min(该班的人数,当前奶茶能喝的奶茶),其中,当前能喝的奶茶 =当前剩下的奶茶 - 该班拥有的奶茶数。
(这题一开始我想到了最蠢的方法,模拟,一个班级一个班级的遍历,但这样做无疑是要超时的)
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
struct cla
{
int a,b;
bool operator < (const cla &other) const
{
if(a>other.a)
return true;
return false;
}
};
cla aa[maxn];
int main()
{
freopen("in.txt","r",stdin);
int t,n;
long long summ,numm,g;
scanf("%d",&t);
while(t--)
{
summ=numm=g=0;//summ保存当前奶茶数,numm记录能喝到奶茶的人数,g表示当前要消耗的奶茶数
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&aa[i].a,&aa[i].b);
summ+=aa[i].b;
}
sort(aa,aa+n);
for(int i=0;i<n;i++)
{
long long tmp=min((long long) aa[i].a,summ-aa[i].b);
g+=tmp;
summ-=tmp;
numm+=tmp;
if(aa[i+1].b<=g)//每次优先到下一个班级去取奶茶
{
g-=aa[i+1].b;
aa[i+1].b=0;
}
else
aa[i+1].b-=g,g=0;
}
printf("%lld\n",numm);
}
return 0;
}