题解:P13750 [NWERC 2024] Limited Library
veni_vedi_veci · · 题解
传送门
P13750 [NWERC 2024] Limited Library
题意
现在有
同时我们希望能放更多艺术品,每层最多放
求在能够放下所有新书的前提下,最多能放多少艺术品,若新书都无法放完,则输出 impossible。
思路
因为求的是放的艺术品数,所以可以用二分来求艺术品数(因为若放
而且因为每层能放的书的数量是一样的,矮书既能放高层又能放矮层,但高书只能放高层,所以最优策略为矮书放矮层,高书放高层。
同理,艺术品放矮层比放高层也要更优。
所以先对每本书和每层书架的高度都升序排序。
接着二分答案,check 中在前
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,x,y,l,r,ans=-1;//先为答案赋值为 -1,若最后还是 -1 则表示一直都没合法过,输出 impossible
vector<int> a,b;
bool check(int k)
{
int j=0;
for(int i=0;i<k&&j<m;i++)//在前 mid 层放 y 本书
{
int cnt=y;
while(cnt--&&j<m&&b[j]<=a[i])
j++;
}
for(int i=k;i<n&&j<m;i++)//在其他层放 x 本书
{
int cnt=x;
while(cnt--&&j<m&&b[j]<=a[i])
j++;
}
return j>=m;//判断书是否放完
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>x>>y;
r=n;
a.resize(n);
b.resize(m);
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<m;i++)
cin>>b[i];
sort(a.begin(),a.end());
sort(b.begin(),b.end());//排序
while(l<=r)//二分答案
{
int mid=(l+r)>>1;
if(check(mid))
ans=mid,l=mid+1;
else
r=mid-1;
}
if(ans==-1)//一直都放不完
cout<<"impossible";
else
cout<<ans;
return 0;
}