二分搜索 最小值的最大值的简单应用(注意区间左开右闭,每次的中心值M=(L+R+1)/2;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
int price,quality;
node(){
}
node(int p,int q){
price=p;quality=q;
}
};
unordered_map<string,vector<node> >mp;
//set<string>st;
int n,b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
//cout.tie(0);
int t;//例子数
//scanf("%d",&t);
cin>>t;
while(t--){
int min_x=1000000010,max_x=-1;
//scanf("%d%d",&n,&b);
cin>>n>>b;
mp.clear();
string type,name;
int price,quality;
for(int i=1;i<=n;i++){
cin>>type>>name>>price>>quality;
mp[type].push_back(node(price,quality));
min_x=min(min_x,quality);
max_x=max(max_x,quality);
}
//最小值最大(左开右闭)
min_x-=1;
ll sum=0;
while(min_x<max_x){
sum=0;
int mid=(max_x+min_x+1)/2;
//st.clear();
for(auto i=mp.begin();i!=mp.end();i++){
int minn=1000000010,flag;
for(int j=0;j<(i->second).size();j++){
if((i->second)[j].quality>=mid){
minn=min((i->second)[j].price,minn);
}
}
sum+=minn;
}
//&&st.size()==mp.size()
if(sum>b){
max_x=mid-1;
}else{
min_x=mid;
}
}
//printf("%d\n",max_x);
cout<<max_x<<endl;
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1000+7;
map<string,int>mp;
struct node{
int p,q;
};
vector<node>a[N];
int cnt=0,n,b;
int check(int M){
long long sum=0;
for(int i=0;i<cnt;i++){
int minn=b+10;
for(int j=0;j<(int)a[i].size();j++){
if(a[i][j].q>=M){
minn=min(minn,a[i][j].p);
}
}
sum+=minn;
if(sum>b) return 0;
}
return 1;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n>>b;
for(int i=0;i<cnt;i++) a[i].clear();
cnt=0;
int L=1000000010,R=0;
for(int i=0;i<n;i++){
string type,name;
int p,q;
cin>>type>>name>>p>>q;
if(mp.count(type)==0){
mp[type]=cnt++;
}
R=max(R,q);
L=min(L,q);
a[mp[type]].push_back({p,q});
}
L-=1;
while(L<R){
int M=(L+R+1)/2;
if(check(M)) L=M;
else R=M-1;
}
cout<<R<<endl;
}
return 0;
}