题解:ABC382C Kaiten Sushi
题目描述
大致意思如下:
有 \(n\) 个人,每个人有一个品味值 \(a_i\),有 \(m\) 道寿司,每道寿司的美味值 \(b_i\),按照从 \(1\) 到 \(m\) 的顺序一次经过每个人。对于每个人,如果当前经过他的寿司美味值 \(b_j \ge a_i\) 则该寿司会被吃掉,并且不会经过下一个人。
请求出第 \(i\) 个寿司是被谁吃掉的,输出编号。如果没有人吃它,则输出 -1。
题目分析
不安发现,第 \(i\) 个寿司如果会被第 \(j\) 人吃掉,那么当且仅当 \(b_i\ge a_j\) 且 \(j\) 最小。也就是说,第 \(i\) 个人能吃到 \(j\) 号寿司的条件为:\(b_j\ge a_i\) 且 \(b_j< a_k(k<i)\),可以理解为之前的人没吃过。这是否意味着从 \(1\) 到 \(n\) 的每个人吃掉的寿司美味值在总体上(只考虑人与人之间的差异)是单调下降的。
那么可以将 \(b_j(j\le n)\) 从大到小排序,每次遍历找到 \(a_i > b_j\) 的临界坐标并存储之前的 \(b_j\) 所对应的答案,下一次 \(a_{i + 1}\) 直接从临界坐标开始找就行。
题目复杂度
总共相当于遍历了所有的寿司,其总复杂度约为 \(\mathcal{O}(m)\)。
代码实现
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 200005;
int a[MAXN], ans[MAXN];
struct Node{
int del, id;
}b[MAXN];
bool cmp(Node x, Node y){
return x.del > y.del;
}
int main(){
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i ++){
cin >> a[i];
}
for(int i = 1; i <= m; i ++){
cin >> b[i].del;
b[i].id = i;
ans[i] = -1;
}
sort(b + 1, b + 1 + m, cmp);
int last = 0;
for(int i = 1; i <= n; i ++){
for(int j = last + 1; j <= m; j ++){
if(b[j].del >= a[i]){
last = j;
ans[b[j].id] = i;
}else{
break;
}
}
}
for(int i = 1; i <= m; i ++){
cout << ans[i] << "\n";
}
return 0;
}
本文来自博客园,作者:AllENdless,转载请注明原文链接:https://www.cnblogs.com/EnDlLesA2010/p/18579837

浙公网安备 33010602011771号