AtCoder Beginner Contest 476_D - Automat
中文题面

看了题目,因为饮料能用面值为k美元的纸币和1美元纸币购买,而甜品只能用1美元纸币,找零只找1美元纸币,所有我能购买最多的商品是受k美元纸币数量\(Y\)限制,所以一开始我是想尽可能用k美元面值的纸币去买饮料。然后如果有剩余的k面值纸币那就去买甜品。。我是这样写的,然后发现3个样例只能过2个
\(Wrong code\)
void solve() {
int n,m ,k ;
cin >> n >> m >> k ;
int x,y ;
cin >> x >> y ;
int cnt = 0 ;
vector<int>a(n),b(m) ;
for(int i = 0;i < n;i++) cin >> a[i] ;
sort(a.begin(),a.end()) ;
for(int j = 0;j < m;j++) cin >> b[j] ;
sort(b.begin(),b.end()) ;
for(int j = 0;j < m;j++){
int mo = b[j] % k ;
if(mo == 0){
int cons1 = b[j] / k ;
if(y - cons1 > 0){
cnt ++ ;
y = y - cons1 ;
}
}
else {
int cons2 = b[j] / k + 1 ;
if(y - cons2 > 0){ cnt ++ ;
y = y - cons2 ;
x = x + k - mo ;
}
}
}
for(int i = 0;i < n;i++){
if(y == 0){
if(x - a[i] > 0){
cnt++ ;
x = x - a[i] ;
}
}
else {
if(a[i] >= y * k){
a[i] -= y * k ;
y = 0 ;
if(x >= a[i]){
cnt++ ;
x -= a[i] ;
}
}
else {
int cons3 = a[i] / k ;
y -= cons3 ;
if(x >= a[i] % k){
x -= a[i] % k ;
cnt ++ ;
}
}
}
}
cout << cnt << "\n" ;
}
后面就去向AI大人寻求帮助了,他说我这样的思想是错的,因为会出现后面饮料单价足够能买更多的甜品,所以只需要暴力枚举购买的饮料数量,剩下的钱买甜品。用前缀和预处理一下买i个甜品所需要的前,和买i个饮料所需的钱和那个需要k面值纸币的数量,然后一直取max,最后输出就可以AC了
\(ACcode\)
void solve(){
int n,m,k ;
cin >> n >> m >> k ;
int x,y ;
cin >> x >> y ;
vector<int>a(n),b(m) ;
for(int i = 0;i < n;i++) cin >> a[i] ;
sort(a.begin(),a.end()) ;
for(int j = 0;j < m;j++){
cin >> b[j] ;
}
sort(b.begin(),b.end()) ;
vector<int>prefix_A(n+1,0),prefix_B(m+1,0) ;
for(int i = 1;i <= n;i++){
prefix_A[i] = prefix_A[i - 1] + a[i - 1] ;
}
for(int j = 1; j <= m;j++){
prefix_B[j] = prefix_B[j - 1] + b[j - 1] ;
}
vector<int>prefixK(m + 1, 0 ) ;
for(int i = 1; i <= m;i++){
prefixK[i] = prefixK[i - 1] + (b[i - 1] + k - 1) / k ;
}
int all = x + k * y ;
int ans = 0 ;
for(int i = 0;i <= m;i++){
if(prefixK[i] > y){
break ;
}
if(all < prefix_B[i]){
break ;
}
int yushu = all - prefix_B[i] ;
int ca = upper_bound(prefix_A.begin(),prefix_A.end(),yushu) - prefix_A.begin() - 1 ;
ans = max(ans,ca + i) ;
}
cout << ans << "\n" ;

浙公网安备 33010602011771号