题解: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;
}
posted @ 2024-12-01 15:42  AllENdless  阅读(32)  评论(0)    收藏  举报