P8837 [传智杯 #3 决赛] 商店

112 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情

[传智杯 #3 决赛] 商店

题目背景

disangan333 想给 disangan233 买一个礼物,于是他和你一起逛商店。

题目描述

nn 名同学去逛商店,店里有 mm 个物品,第 ii 人有 wiw_i 块钱,第 ii 个物品价格 cic_i 元。

每个人至多买一个物品,每个物品只能被买一次,问最多有多少人能买到物品。

对于所有数据,n,m105n,m \leq 10^5wi,ci109w_i,c_i\leq 10^9

输入格式

输入共 33 行。

11 行输入 22 个正整数 n,mn,m

22 行输入 nn 个整数 w1wnw_1\ldots w_nwiw_i 表示第 ii 人的钱。

33 行输入 mm 个整数 c1cmc_1\ldots c_mcic_i 表示第 ii 个物品的价格。

输出格式

对于所有数据,n,m105n,m \leq 10^5wi,ci109w_i,c_i\leq 10^9

样例 #1

样例输入 #1

15 20
4 3 9 10 7 7 5 3 6 1 8 6 6 1 5 
12 4 1 9 8 5 8 6 4 5 18 8 14 9 9 7 20 11 8 19

样例输出 #1

10

思路分析

看到这题怎么办?该怎么做呢?
首先想想暴力贪心循环做

  • 先对商品价格和学生的钱进行排序
  • 然后对于每一位同学,从小到大找到商品价格最小的且可以满足同学本身的钱,然后次数++
  • 但是我们会发现10510^5×10510^5是毫无疑问会超时!那么得进行优化

优化思路

  • 1.先对商品的价格和学生的钱进行一个sort排序(当然也可以自己写)
  • 2.想想双指针算法,两个指针对应两个数组
  • 3.这里有比较巧妙的事情——根据贪心的思维,对于钱从小到大的学生
    • 如果可以在已排序好的商品价格里面找到第一个自己可以买的东西,那么次数加一
    • 否则的话,这名学生无法购买东西,那么这时就直接跳过即可

代码呈现

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
	int n, m;
	cin >> n >> m;
	vector<int>a, b;
	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		a.push_back(x);
	}
	for (int i = 0; i < m; i++) {
		int x;
		cin >> x;
		b.push_back(x);
	}
	sort(a.begin(), a.end());
	sort(b.begin(), b.end());
	int res = 0;
	int i = 0, j = 0;
	while (i < a.size() && j < b.size()) {
		if (a[i] >= b[j]) {
			j++;
			res++;
		}
		i++;
	}
	cout << res;
}

PS:第三届的中间的题目了竟然还这么容易!贪心加模拟就可以随便做~