这天,小颜在整理他的卡牌。
他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i∈[1,n]), 且第 i 种卡牌现有 ai 张。
而如果有 n 张卡牌,其中每种卡牌各一张,那么这 n 张卡牌可以被称为一套牌。小颜为了凑出尽可能多套牌,拿出了 m 张空白牌, 他可以在上面写上数 i,将其当做第 i 种牌来凑出套牌。然而小颜觉得手写的牌不太美观,决定第 i 种牌最多手写 bi 张。
请问小颜最多能凑出多少套牌?
输入描述
输入共 3 行,第一行为两个正整数 n,m 。
第二行为 n 个正整数 a1,a2,…,an 。
第三行为 n 个正整数 b1,b2,…,bn 。
输出描述
一行,一个整数表示答案。
用例输入 1
4 5 1 2 3 4 5 5 5 5
用例输出 1
3
提示
样例说明:这 5 张空白牌中,拿 2 张写 1,拿 1 张写 2,这样每种牌的牌数就变为了 3,3,3,4,可以凑出 3 套牌,剩下 2 张空白牌不能再帮助小明凑出一套。
对于 30% 的数据,保证 n≤2000;
对于 100% 的数据,保证 n≤2×105;ai,bi≤n;m≤n2 。
直接上代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n;
ll m;
struct card
{
int a, b;
card(int aa = 0, int bb = 0)
{
a = aa;
b = bb;
}
};
vector<card> vc;
bool cmp(card a, card b)
{
return a.a < b.a;
}
bool jd(int x)
{
ll tm = m;
for (int i = 0; i < n; i++)
{
if (vc[i].a >= x)
break;
if (vc[i].a + vc[i].b < x)
return false;
tm -= (x - vc[i].a);
if (tm < 0)
return false;
}
return true;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
card t;
cin >> t.a;
vc.push_back(t);
}
for (int i = 0; i < n; i++)
cin >> vc[i].b;
sort(vc.begin(), vc.end(), cmp);
//二分可能取到的最小值
int l = vc[0].a, r = 5 * n + 5;
while (l < r)
{
int mid = (l + r + 1) / 2;
if (jd(mid))
l = mid;
else
r = mid - 1;
}
cout << l;
return 0;
}