针对CSP-J/S的每日一练:Day7

一、审题

题目描述

在某个游戏里,玩家可以给自己的角色穿上各种装备,每件装备都有自己的品质和属性。角色的属性可以通过穿戴的装备进行累加得到。

游戏中有 n n n 种装备,编号从1到 n n n,每件装备有一个品质 q i q_i qi 和三个属性值 a i a_i ai b i b_i bi c i c_i ci。一件装备的属性可以简单地看做是其品质 q i q_i qi 与三个属性 a i a_i ai b i b_i bi c i c_i ci 的乘积,即 p i = q i × a i × b i × c i p_i=q_i\times a_i\times b_i\times c_i pi=qi×ai×bi×ci

一位玩家的角色已经穿戴了 m m m 件装备,其中第 i i i 件装备的编号为 p i p_i pi。角色的属性值可以分别表示为 A = ∑ i = 1 m a i A=\sum_{i=1}^m a_i A=i=1mai B = ∑ i = 1 m b i B=\sum_{i=1}^m b_i B=i=1mbi 以及 C = ∑ i = 1 m c i C=\sum_{i=1}^m c_i C=i=1mci

现在,角色想要升级,需要找到一个品质值 Q Q Q 最小的装备进行替换,即找到编号 j j j 使得 q j < Q q_jqj<Q p j > a j × b j × c j p_j>a_j\times b_j\times c_j pj>aj×bj×cj。如果存在多个符合要求的装备,那么应该选择编号最小的一个进行替换。

请你编写程序,求出符合要求的装备编号 j j j

输入格式

第一行两个整数 n n n m m m,分别表示装备总数和玩家装备数。

接下来 n n n 行,每行描述一个装备。其中第 i i i 行包含四个整数 q i q_i qi a i a_i ai b i b_i bi c i c_i ci,分别表示第 i i i 件装备的品质和三个属性值。

接下来 m m m 行,每行描述一件已经穿戴的装备。其中第 i i i 行包含一个整数 p i p_i pi,表示该装备的编号。

输出格式

输出一个整数,表示符合要求的装备编号 j j j。如果不存在任何一件符合要求的装备,输出-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 ≤ 100 1\leq n\leq 100 1n100 1 ≤ m ≤ 50 1\leq m\leq 50 1m50

对于100%的评测用例, 1 ≤ n ≤ 1 0 6 1\leq n\leq10^6 1n106 1 ≤ m ≤ 1 0 5 1\leq m\leq 10^5 1m105 1 ≤ q i ≤ 1 0 4 1\leq q_i\leq 10^4 1qi104 1 ≤ a i , b i , c i ≤ 100 1\leq a_i,b_i,c_i\leq 100 1ai,bi,ci100 1 ≤ p i ≤ 1 0 9 1\leq p_i\leq 10^9 1pi109

提示

对于50%的数据,可以直接暴力枚举符合条件的装备,然后选择品质最小的一个。时间复杂度为 O ( n m ) O(nm) O(nm)

对于100%的数据,可以使用哈希表维护已经穿戴的装备编号,然后对于每个品质小于当前穿戴装备品质的装备,计算其属性值,如果符合要求则更新答案。同时,可以使用前缀和优化存储和计算属性值。时间复杂度为 O ( n ) O(n) O(n)

题目来源:CSP-J 2020年模拟赛试题

二、思路

步骤一:读懂题目并理解要求

首先,需要读懂题目并理解其中的问题:通过一种数据结构算法,找到符合要求的一件装备,从而求得其编号。在本题中,找到符合要求的装备需要满足两个条件:品质 q j q_j qj 小于指定值 Q Q Q,同时其属性 p j p_j pj 大于 a j × b j × c j a_j \times b_j \times c_j aj×bj×cj。其中, p j = q j × a j × b j × c j p_j=q_j\times a_j \times b_j \times c_j pj=qj×aj×bj×cj

步骤二:确定算法

对于这道题目,最直接想到的方法是遍历所有可能的装备,找到符合要求的装备。但是这样的时间复杂度是 O ( n m ) O(nm) O(nm),即使 n n n m m m 比较小也会超时。因此我们需要更加高效的算法解决此问题。

在本题中,我们可以通过哈希表存储已经穿戴的装备编号,然后对于每个品质小于当前穿戴装备品质的装备,计算其属性值,如果符合要求则更新答案。同时,可以使用前缀和优化存储和计算属性值。由于哈希表的查找时间是常数级别的,因此时间复杂度是 O ( n ) O(n) O(n),可以通过此题。

步骤三:实现代码

在确定好算法之后,我们就可以实现代码来解决本题。需要注意以下几点:

  • 首先需要使用哈希表存储已经穿戴的装备编号,即将 m m m 个编号存储到哈希表中。
  • 接着循环遍历 n n n 种装备,找到符合条件的装备并更新答案。同时,可以使用前缀和优化存储和计算属性值。
  • 最后输出答案即可。

三、参考代码

#include 
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;
}

你可能感兴趣的:(算法,c++)