AC通道:
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1972
(好长啊)
组装电脑
Description
你有
b
块钱,想要组装一台电脑。给出
Input
输入的第一行为测试数据组数
每组数据的第一行为两个正整数
n
(
以下
n
行每行描述一个配件,依次为种类、名称、价格和品质因子。
其中,价格为不超过
品质因子是不超过
109
的非负整数(越大越好);
种类和名称则又不超过
20
个字母、数字和下划线组成。
输入保证总是有解。
Output
对于每组数据,输出配件最小品质因子的最大值。
Sample Input
1
18 800
processor 3500_MHz 66 5
processor 4200_MHz 103 7
processor 5000_MHz 156 9
processor 6000_MHz 219 12
memory 1_GB 35 3
memory 2_GB 88 6
memory 4_GB 170 12
mainbord all_onboard 52 10
harddisk 250_GB 54 10
harddisk 500_FB 99 12
casing midi 36 10
monitor 17_inch 157 5
monitor 19_inch 175 7
monitor 20_inch 210 9
monitor 22_inch 293 12
mouse cordless_optical 18 12
mouse microsoft 30 9
keyboard office 4 10
Sample Output
9
Solution
首先,我们可以二分答案。
假设答案为 x ,我们需要判断的是就是会不会超过预算。
我们可以把所有品质因子小于
将这个总价格与预算作比较,就可以判断有无解了。
这里有一个问题,
std::ios::sync_with_stdio(false);
我加上这条语句后,RE了;可去掉后,就AC了。
求神犇解释。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
struct Node{
string cases;
int price,v;
};
int cass[1010][1010];
Node node[1010];
int T,ans;
int n,b,cnt=0,MAXN;
map<string,int>maps;
string meaningless;
bool cmp(int a,int b){
return node[a].price<node[b].price;
}
inline int Max(int a,int b){
return a>b?a:b;
}
inline int in(){
int ans=0;
char x=getchar();
while(x<'0'||x>'9')x=getchar();
while(x>='0'&&x<='9'){ans=ans*10+x-'0';x=getchar();}
return ans;
}
void init(){
memset(cass,0,sizeof cass);
cnt=0;
MAXN=0;
maps.clear();
n=in();b=in();
for(int i=1;i<=n;i++){
cin>>node[i].cases>>meaningless;
node[i].price=in();
node[i].v=in();
if(!maps.count(node[i].cases)){
maps[node[i].cases]=++cnt;
cass[cnt][++cass[cnt][0]]=i;
}
else{
int tmp=maps[node[i].cases];
cass[tmp][++cass[tmp][0]]=i;
}
MAXN=Max(node[i].v,MAXN);
}
for(int i=1;i<=cnt;i++)
sort(cass[i]+1,cass[i]+cass[i][0]+1,cmp);
}
bool pan(int s){
int ss=0;
for(int i=1;i<=cnt;i++){
bool flag=true;
for(int j=1;j<=cass[i][0];j++){
if(node[cass[i][j]].v>=s){
ss+=node[cass[i][j]].price;
flag=false;
break;
}
}
if(flag)return false;
if(ss>b)return false;
}
return true;
}
void work(){
ans=0;
int l=0,r=MAXN;
while(l<=r){
int mid=(l+r)/2;
bool flag=pan(mid);
if(flag){
if(ans<mid)ans=mid;
if(l!=mid+1)l=mid+1;
else break;
}
else{
if(r!=mid-1)r=mid-1;
else break;
}
}
cout<<ans<<endl;
}
int main(){
//ios::sync_with_stdio(false);加上这条后就会RE。求神犇解释。
T=in();
for(int i=1;i<=T;i++){
init();
work();
}
return 0;
}