2026.06.01 作业 - AT_abc460_c [ABC460C] Sushi
题目描述
现有 \(N\) 份醋饭(シャリ)、\(M\) 份配料食材(ネタ)。
第 \(i\) 份醋饭重量 \(A_i\),第 \(j\) 份配料重量 \(B_j\)。
一个寿司需要1份醋饭 + 1份配料配对制作,配对限制:
鱼肉重量 ≤ 醋饭重量 × 2。
每份醋饭、每份配料最多只用一次。
求最多能做出多少个寿司。
输入格式
第一行:\(N\ M\)
第二行:\(A_1\ A_2\dots A_N\)
第三行:\(B_1\ B_2\dots B_M\)
输出格式
输出最大可制作寿司数量。
样例1
输入:
4 5
4 2 1 8
14 9 3 2 9
输出:3
说明:最多凑3组合法配对。
样例2
3 3
5 5 3
11 1000 1000
输出:0
解释:\(11>5\times2\),全部配料都超标,无法配对。
样例3
输出:5
数据范围
\(1\le N,M\le 2\times10^5,\ 1\le A_i,B_i\le 10^9\)
标准贪心思路
- 数组 \(A\)、\(B\) 分别升序排序;
- 双指针:\(i\)(醋饭从头),\(j\)(配料从头);
- 贪心策略,尽量选择小的 配料 。若 \(B[j]\le 2\times A[i]\):配对成功,答案+1,\(i++,j++\);
否则当前配料太大无法匹配当前小醋饭,\(j++\)。
AC代码(适配本题条件)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int n,m;
int a[MAXN],b[MAXN];
int main() {
cin>>n>>m;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=m;i++) scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+m);
int k=0; // a数组指针
int Ans=0;
// 枚举每个食材b[i]
for (int i=1;i<=m;i++) {
k++;
// 条件:a[k]*2 < b[i] → 这个醋饭太小用不了,换下一个醋饭
while (k<=n && 1LL*a[k]*2 < b[i]) k++;
if (k<=n) Ans++;
else break;
}
cout<<Ans<<endl;
return 0;
}

浙公网安备 33010602011771号