一、审题
题目描述
在某个游戏里,玩家可以给自己的角色穿上各种装备,每件装备都有自己的品质和属性。角色的属性可以通过穿戴的装备进行累加得到。
游戏中有 nnn 种装备,编号从1到 nnn,每件装备有一个品质 qiq_iqi 和三个属性值 aia_iai、bib_ibi 和 cic_ici。一件装备的属性可以简单地看做是其品质 qiq_iqi 与三个属性 aia_iai、bib_ibi 与 cic_ici 的乘积,即 pi=qi×ai×bi×cip_i=q_i\times a_i\times b_i\times c_ipi=qi×ai×bi×ci。
一位玩家的角色已经穿戴了 mmm 件装备,其中第 iii 件装备的编号为 pip_ipi。角色的属性值可以分别表示为 A=∑i=1maiA=\sum_{i=1}^m a_iA=∑i=1mai、B=∑i=1mbiB=\sum_{i=1}^m b_iB=∑i=1mbi 以及 C=∑i=1mciC=\sum_{i=1}^m c_iC=∑i=1mci。
现在,角色想要升级,需要找到一个品质值 QQQ 最小的装备进行替换,即找到编号 jjj 使得 qj<Qq_j<Qqj<Q 且 pj>aj×bj×cjp_j>a_j\times b_j\times c_jpj>aj×bj×cj。如果存在多个符合要求的装备,那么应该选择编号最小的一个进行替换。
请你编写程序,求出符合要求的装备编号 jjj。
输入格式
第一行两个整数 nnn 和 mmm,分别表示装备总数和玩家装备数。
接下来 nnn 行,每行描述一个装备。其中第 iii 行包含四个整数 qiq_iqi、aia_iai、bib_ibi 和 cic_ici,分别表示第 iii 件装备的品质和三个属性值。
接下来 mmm 行,每行描述一件已经穿戴的装备。其中第 iii 行包含一个整数 pip_ipi,表示该装备的编号。
输出格式
输出一个整数,表示符合要求的装备编号 jjj。如果不存在任何一件符合要求的装备,输出-1。
样例输入
5 2 2 1 2 3 3 1 1 1 1 2 4 5 4 6 7 1 5 1 1 2 2 4
样例输出
3
数据说明
对于50%的评测用例,1≤n≤1001\leq n\leq 1001≤n≤100,1≤m≤501\leq m\leq 501≤m≤50。
对于100%的评测用例,1≤n≤1061\leq n\leq10^61≤n≤106,1≤m≤1051\leq m\leq 10^51≤m≤105,1≤qi≤1041\leq q_i\leq 10^41≤qi≤104,1≤ai,bi,ci≤1001\leq a_i,b_i,c_i\leq 1001≤ai,bi,ci≤100,1≤pi≤1091\leq p_i\leq 10^91≤pi≤109。
提示
对于50%的数据,可以直接暴力枚举符合条件的装备,然后选择品质最小的一个。时间复杂度为 O(nm)O(nm)O(nm)。
对于100%的数据,可以使用哈希表维护已经穿戴的装备编号,然后对于每个品质小于当前穿戴装备品质的装备,计算其属性值,如果符合要求则更新答案。同时,可以使用前缀和优化存储和计算属性值。时间复杂度为 O(n)O(n)O(n)。
题目来源:CSP-J 2020年模拟赛试题
二、思路
步骤一:读懂题目并理解要求
首先,需要读懂题目并理解其中的问题:通过一种数据结构算法,找到符合要求的一件装备,从而求得其编号。在本题中,找到符合要求的装备需要满足两个条件:品质 qjq_jqj 小于指定值 QQQ,同时其属性 pjp_jpj 大于 aj×bj×cja_j \times b_j \times c_jaj×bj×cj。其中,pj=qj×aj×bj×cjp_j=q_j\times a_j \times b_j \times c_jpj=qj×aj×bj×cj。
步骤二:确定算法
对于这道题目,最直接想到的方法是遍历所有可能的装备,找到符合要求的装备。但是这样的时间复杂度是 O(nm)O(nm)O(nm),即使 nnn 和 mmm 比较小也会超时。因此我们需要更加高效的算法解决此问题。
在本题中,我们可以通过哈希表存储已经穿戴的装备编号,然后对于每个品质小于当前穿戴装备品质的装备,计算其属性值,如果符合要求则更新答案。同时,可以使用前缀和优化存储和计算属性值。由于哈希表的查找时间是常数级别的,因此时间复杂度是 O(n)O(n)O(n),可以通过此题。
步骤三:实现代码
在确定好算法之后,我们就可以实现代码来解决本题。需要注意以下几点:
- 首先需要使用哈希表存储已经穿戴的装备编号,即将 mmm 个编号存储到哈希表中。
- 接着循环遍历 nnn 种装备,找到符合条件的装备并更新答案。同时,可以使用前缀和优化存储和计算属性值。
- 最后输出答案即可。
三、参考代码
#include <iostream>
using namespace std;
int main()
{
// 读入数据
int n, m, Q;
cin >> n >> m >> Q;
int q[m], a[m], b[m], c[m];
for (int i = 0; i < m; i++)
{
cin >> q[i] >> a[i] >> b[i] >> c[i];
}
// 处理数据
int ans = -1;
int has_worn[m+1] = {0}; // 哈希表记录已穿戴的装备
for (int i = 1; i <= n; i++)
{
int qq, aa, bb, cc;
cin >> qq >> aa >> bb >> cc;
int p = qq * aa * bb * cc; // 计算当前装备的属性值
for (int j = 0; j < m; j++)
{
if (q[j] < qq && !has_worn[j+1] && p > a[j] * b[j] * c[j]) {
ans = j + 1;
a[j] = b[j] = c[j] = 0; // 将已穿戴的装备清空
}
}
// 更新已穿戴的装备编号
if (qq <= Q)
{
has_worn[ans] = 1;
}
}
// 输出答案
cout << ans;
return 0;
}
文章讨论如何利用哈希表和前缀和优化算法解决游戏角色在升级时寻找替换装备的问题。
1094

被折叠的 条评论
为什么被折叠?



