首页 > 其他分享 >习题加餐4. 鸡哥的购物挑战

习题加餐4. 鸡哥的购物挑战

时间:2024-03-19 20:33:18浏览次数:15  
标签:el 鸡哥 int sp long 购物车 商品 加餐 习题

 

问题描述

鸡哥在“无尽的夏日”购物节上看中了一系列的商品,这些商品的价格各不相同。然而,鸡哥的购物车有一条特殊的规则:购物车中的商品数量必须是偶数个。

鸡哥希望在满足购物车规则的前提下,选择总价值最高的商品。他将商品的价格列表给了你,希望你能帮他计算出他能购买到的商品的最高总价值是多少。

输入格式

第一行包含一个整数N(2≤N≤10⁵),表示商品的数量。

第二行包含N个整数,表示每个商品的价格A₃(-10⁹≤A;≤10⁹)。

输出格式

输出一行,表示鸡哥能购买到的商品的最高总价值。

样例输入

5

12345

样例输出

14

运行限制

语言

最大运行时间

最大运行内存

C

1s

256M

C++

1s

256M

我的答案:第一版本连编译都没通过

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
int main(){
  int N=0,sum=0;
  cin >> N;
  vector<LL> a[N];//在这发现要用方括号
  for(int i=0;i<N;i++){
    cin >> a[i];
  }
  if(N%2!=0){
    sort(a.begin(),a.end()+1);//忘了sort是升序还是降序了
    for(int j=0;j<a.size();j++){
      sum=sum+a[j+1];
    }
  }else{
    for(int k=0;k<N;k++){
      sum=sum+a[k];
    }
  }
  cout << sum;
}

错误原因:

  1. 读取向量元素时使用 a[i] 而不是 a(i)a(i) 的语法在 C++ 中是不正确的,应当使用方括号 [] 以访问向量的元素。

  2. sort 函数调用中,a.end()+1 是不正确的。sort 函数的范围是左闭右开的,因此应当直接使用 a.begin()a.end() 作为参数。如果你想要排序整个向量,应该使用 sort(a.begin(), a.end())

  3. 在处理 sum 时,你在 if(N%2!=0) 分支中的循环中使用了 a(j+1),这将导致越界访问,因为 j+1 在循环的最后一次迭代时会超出向量的最大索引。应当使用 a[j] 来累加向量中的元素。

  4. 关于 sort 函数的默认行为,它是按照升序排序的。如果你需要按照降序排序,可以使用 sort 的第三个参数,比如 sort(a.begin(), a.end(), greater<LL>())

修改后的代码:我以为对了还是错了

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;

int main() {
    int N = 0;
    LL sum = 0; // 使用 LL 来保持一致性,避免在大数相加时可能的溢出
    cin >> N;
    vector<LL> a(N);
    for (int i = 0; i < N; i++) {
        cin >> a[i]; // 使用方括号访问向量元素
    }
    if (N % 2 != 0) {
        sort(a.begin(), a.end()); // 使用标准的 sort 函数排序
        for (int j = 0; j < a.size(); j++) {
            sum += a[j]; // 正确累加元素
        }
    } else {
        for (int k = 0; k < N; k++) {
            sum += a[k];
        }
    }
    cout << sum;
    return 0;
}

错误原因没看到商品价格可能是负数,以后要对题目条件仔细看,也暴露出本人的思维不够严谨 


正确答案:

解题思路:

 源代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
    ll sp = 0;
    int mn = -1e9 - 1, mp = 1e9 + 1, np = 0;
    int n; cin >> n;
    for (int i = 0; i < n; i += 1) {
        int el; cin >> el;
        if (el > 0) {
            if (mp > el) {
                mp = el;
            }
            sp += el;
            np += 1;
        } else if (mn < el) {
            mn = el;
        }
    }
    if (np % 2) {
        sp = max(sp - mp, sp + mn);
    }
    cout << sp << '\n';
    return 0;
}

 


我的理解: 

一、信息(题目的有用信息)

  • 商品数量要求:购物车中的商品数量必须是偶数。
  • 价格正负:商品价格可能为正也可能为负。
  • 总价值最大化:目标是使购物车中的商品总价值最大。

二、分析(包括每个信息的作用和思考过程)

  • 贪心策略:首先,优先选择价格为正的商品,因为这会直接增加总价值。
  • 处理奇数数量的正价商品:如果正价商品的数量是奇数,我们需要决定是移除一个正价商品还是添加一个负价商品来满足偶数数量的要求。
  • 变量初始化和维护
    • sp(购物车商品总价值)
    • np(购物车商品数量)
    • mn(负价商品中的最大值)
    • mp(正价商品中的最小值)

三、算法设计

  1. 初始化:设置初始变量,包括商品总价值、商品数量、正价商品的最小值、负价商品的最大值。
  2. 遍历商品:对于每个商品价格进行判断:
    • 如果价格大于0,加入购物车,更新总价值和商品数量,同时更新最小正价商品值。
    • 如果价格小于等于0,更新最大负价商品值。
  3. 调整购物车:如果购物车中商品数量为奇数,比较移除一个最小正价商品和添加一个最大负价商品的情况,选择能使总价值最大的方案。
  4. 输出结果:最后输出购物车商品的最高总价值。

四、代码实现(用C++)

#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ll sp = 0;
    int mn = -1e9 - 1, mp = 1e9 + 1, np = 0;
    int n; cin >> n;
    for (int i = 0; i < n; i += 1) {
        int el; cin >> el;
        if (el > 0) {
            if (mp > el) {
                mp = el;
            }
            sp += el;
            np += 1;
        } else if (mn < el) {
            mn = el;
        }
    }
    if (np % 2) {
        sp = max(sp - mp, sp + mn);
    }
    cout << sp << '\n';
    return 0;
}

五、实现代码过程中可能遇到的问题

  • 整数溢出:由于商品价格范围很大,必须使用足够大的整数类型来避免溢出(如 long long)。
  • 理解正负价值商品的策略:理解负价商品可能带来的总价值增加是问题的关键。
  • 正确选择最小正价商品和最大负价商品:要正确维护这两个变量,这对于算法能否得到正确结果至关重要。

上述算法的时间复杂度为 O(N),因为它通过单次遍历所有商品来实现,这使得它适合处理大量数据的情况。

标签:el,鸡哥,int,sp,long,购物车,商品,加餐,习题
From: https://blog.csdn.net/tang7mj/article/details/136852199

相关文章

  • Hive SQL必刷练习题:向用户推荐朋友收藏的商品(两种思路)
    问题需求:需要请向所有用户推荐其朋友收藏但是用户自己未收藏的商品,请从好友关系表(friendship_info)和收藏表(favor_info)中查询出应向哪位用户推荐哪些商品。期望结果如下:1)部分结果展示user_id(用户id)sku_id(应向该用户推荐的商品id)101210141017101910181011110112)相关表结构......
  • 第三章课后习题
    一、分析计算机页面布局   实现如下图所示的效果图实现步骤     在zy3.wxml中写下以下代码:<viewclass="c1"><viewclass="ly-top"><viewclass="sc">3×8</view></view><viewclass="ly-bottom">......
  • pyCharm oj 习题 列表合并、去重、排序
    列表合并、去重、排序ProblemDescription从键盘输入两个数列,构成两个列表list1、list2,合并这两个列表为list3,将list3去掉重复元素、降序排序后生成list4.InputDescription输入两个数列,以英文逗号分隔OutputDescription输出列表list1、list2、list3、list4SampleInpu......
  • 线性表章节课后习题答案集锦
    目录2.52.62.72.82.92.102.112.122.132.5/*要比较两个单词在字典中的顺序,可以逐个比较它们的字符。首先比较两个单词的第一个字符,如果相同,则继续比较下一个字符,直到找到不同的字符或者某个单词比较完毕。比较时,可以利用ASCII码进行比较,因为字母在ASCII码中是按顺......
  • 蓝桥练习题-K倍区间
    16.k倍区间-蓝桥云课(lanqiao.cn)首先,看到这个题,想到暴力求解,但显然,数据过大,暴力法过不了;然后看到了一个办法:对所有元素的前缀和取K的模,若s[i],s[j]相同,则在j-1到i的区间内,区间和为K的倍数。C++代码:#include<iostream>#include<queue>usingnamespacestd;ty......
  • 蓝桥练习题-分考场
    0分考场-蓝桥云课(lanqiao.cn)思路:暴力dfs,dfs(x,room)x为待放入教室的人,room为当前最大有几号教室,对x依次遍历教室1到教室room,若某教室当前没该同学认识的人,直接放入,接着放下一个人,若room个教室里都存在x认识的人,即x不能放入任何教室,则在开辟一块新教室放入该同学,dfs结束......
  • 数组练习-小习题
    多个字符从两端开始移动,向中间汇聚输出,例如:打印Hello,word!第一个打印出来H(左一),然后打印!(右一),接着e(右二),下面是d(左二).......依次打印,这里介绍一个关键字:strlen(),用来测量字符串的长度,注意字符串如果带有"\0",strlen是不计算\0的,只计算\0之前的字符数。system(“cls”):清理屏幕。#i......
  • dp 练习题 2024.3.14
    ARC070ENarrowRectangles题意:平面上有\(n\)个矩形,左下角点坐标为\((l_i,i-1)\),右上角点坐标为\((r_i,i)\)。每次把一个矩形沿着横轴方向移动一个长度单位,求移动多少次使得任意两个相邻矩形存在交点。\(1\len\le10^5,\space1\lel_i<r_i\le10^9\)考虑最简单的dp,设\(......
  • Markdown的习题
    markdown的使用说明习题1:将这段话改为2级标题习题2试着在你的’Typora’中编辑下面的内容:这是第一行这是第2行这是补充内容这是第3行习题3将下面的内容改为指定的格式要求:黑体斜体下划线高亮黑体加下划线,并高亮显示拓展题:试着输入1*2*3…*99,如何解决*不显示......
  • C语言入门学习 --- 9.编程练习题
    1.正整数A和正整数B的最小公倍数是指能被A和B整除的最小的正整数,设计一个算法,求输入A和B的最小公倍数。输入描述:输入两个正整数A和B。输出描述:输出A和B的最小公倍数。输入:57输出:35#include<stdio.h>intmain(){ inta=0; intb=0; inti=0; scanf("%d%......