【QED】学以致用

题目背景

2023年9月7日,一年一度的大学生数学建模竞赛开始了。众所周知,数学建模竞赛的C题是数据分析和处理题。然而今年的数据量非常大,最大的一个文件有878503条记录,巨大的数据量让很多选手都非常头疼。

题目描述

学过编程语言的你一定知道编程语言的运算速度非常快,想必如果你参加了今年的数学建模竞赛并且选择了C题的话一定能学以致用。下面是数据处理的一部分问题,一起来练练手吧。

现给定一家超市近三年的蔬菜销售记录,每一条销售记录有以下信息:

1.销售日期;

2.销售的蔬菜的编号;

3.该蔬菜的销售量。

现在需要你设计一个程序,可以满足以下要求:

输入蔬菜编号、起始日期和终止日期,则能输出该编号的蔬菜在这一段时间的总销售量。

输入格式

1.第一行一个正整数 n n n,表示有 n n n 条销售记录。( 1 ≤ n ≤ 1 0 6 1\leq n \leq 10^6 1n106

2.接下来会有 n n n 行输入,每一行 2 2 2 个字符串 T 、 I D T、ID TID 和一个整数 W W W,分别表示销售时间、蔬菜编号和销售量。(数据保证 T T T 为 YYYY-MM-DD 的形式表示的时间、符合实际、按照时间顺序并且所有数据都在2020、2021、2022、2023四年内;ID为由15个数字字符组成的字符串,且保证不同的字符串至多251个;整数 W W W 满足 − 2 × 1 0 5 ≤ W ≤ 2 × 1 0 5 -2\times 10^5 \leq W \leq 2\times 10^5 2×105W2×105

3.接下来有一个正整数 q q q , 表示询问的次数。( 1 ≤ q ≤ 1 0 6 1\leq q \leq 10^6 1q106

4.每次询问会输入 3 3 3 个参数 I D 、 T s 、 T d ID、T_s、 T_d IDTsTd ,表示:询问在 [ T s , T d ] [T_s, T_d] [Ts,Td] 时间内,编号为 I D ID ID 的蔬菜的总销售量。( T s 、 T d T_s、T_d TsTd 保证在输入的 n n n 条销售记录中出现过)

输出格式

对于 q q q 次询问,每次询问,输出一行一个整数,表示在 [ T s , T d ] [T_s, T_d] [Ts,Td] 时间内,编号为 I D ID ID 的蔬菜的总销售量

测试样例

9
2020-07-01 102900005117056 396
2020-07-01 102900005115960 849
2020-07-01 102900005117056 409
2022-02-20 102900005115779 477
2022-02-20 102900005116899 389
2022-02-20 102900005115779 426
2023-06-30 106949711300259 1000
2023-06-30 106949711300259 1000
2023-06-30 102900011030059 1000
5
102900005117056 2020-07-01 2023-06-30
102900005115779 2022-02-20 2022-02-20
102900005115960 2022-02-20 2023-06-30
102900005116899 2022-02-20 2023-06-30
106949711300259 2020-07-01 2023-06-30
805
903
0
389
2000

思路

本题是想要询问一个特定编号的数字的区间出现次数和,对于每一个特定的编号的存储,我们可以使用一个哈希来进行存储,然后题目中的时间都是严格递增的,我们不需要进行额外的排序处理,可以直接线性判断或者二分查找都可以

核心代码

代码来自锕狗:

#include<bits/stdc++.h>
#define endl '\n'
using ld=long double;
using ll=long long;
using namespace std;

int n,q;
unordered_map<string,map<string,ll>> a;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr); cout.tie(nullptr);

	cin>>n;
	string x,y,z;
	for(int i=1;i<=n;i++)
	{
		cin>>x>>y>>z;
		a[y][x]+=stoi(z);
	}
	cin>>q;
	while(q--)
	{
		cin>>x>>y>>z;
		ll ans=0;
		for(auto &t: a[x])
		{
			if(t.first<y)
				continue;
			if(t.first>z)
				break;
			ans+=t.second;
		}
		cout<<ans<<endl;
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要AC的dly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值