[算法题]比那名居的桃子

题目链接: 比那名居的桃子

滑动窗口:

有两个变量表示区间的端点, 不断累加快乐值和羞耻度, 当窗口中的元素大于 k 时, 更新左端点, 缩小区间并修改快乐值和羞耻度, 当窗口中的元素等于 k 时, 判断当前窗口的快乐值是否比历史上的最大快乐值还大, 大于则更新快乐值, 如果相等, 再比较羞耻度, 羞耻度低也需要更新, 并记录最大快乐值是在第几天开始吃桃子, 直到遍历结束, 题解代码:

// 1.滑动窗口
#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int main()
{
    int n, k;
    cin >> n >> k;
    vector<long> happy(n); //快乐值
    vector<long> shame(n); //羞耻度
    //输入
    for(int i = 0; i < n; ++i)
    {
        cin >> happy[i];
    }
    for(int i = 0; i < n; ++i)
    {
        cin >> shame[i];
    }
    int day = 0; //记录结果
    long cur_h = 0; //当前区间的快乐值
    long cur_s = 0; //当前区间的羞耻度
    long max_h = 0; //最大的快乐值
    long min_s = 0; //最小的羞耻度
    //滑动窗口区间[begin,end]
    int begin = 0;
    int end = 0;
    while(end < n)
    {
        cur_h += happy[end];
        cur_s += shame[end];
        //更新区间
        if(end - begin + 1 > k)
        {
            cur_h -= happy[begin];
            cur_s -= shame[begin];
            begin++;
        }
        //更新day,max_h,max_s
        if(end - begin + 1 == k)
        {
            //快乐值最大直接更新
            if(cur_h > max_h)
            {
                day = begin + 1;
                max_h = cur_h;
                min_s = cur_s;
            }
            //快乐值相同,但羞耻度较小,也更新
            else if(cur_h == max_h && cur_s < min_s) 
            {
                day = begin + 1;
                min_s = cur_s;
            }
        }
        end++;
    }
    cout << day << endl; //输出结果
    return 0;
}

前缀和:

通过两个数组存储快乐值和羞耻度的各前缀和, 注意取出第 i 天的前缀和时需要用第 i 天的前缀和减去 i-k 天的前缀和, 更新规则和滑动窗口中的一致, 题解代码如下:

// 2.前缀和
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int n, k;
    cin >> n >> k;
    vector<long> happy(n + 1); //快乐值前缀和
    vector<long> shame(n + 1); //羞耻度前缀和
    //输入+求前缀和
    for(int i = 1; i <= n; ++i)
    {
        cin >> happy[i];
        happy[i] += happy[i - 1];
    }
    for(int i = 1; i <= n; ++i)
    {
        cin >> shame[i];
        shame[i] += shame[i - 1];
    }
    int day = 0; //记录结果
    long  h_max = 0; //最大的快乐值
    long s_min = 0; //最小的羞耻度
    for(int i = 0; i <= n - k; ++i)
    {
        long h_cur = happy[i + k] - happy[i];
        long s_cur = shame[i + k] - shame[i];
        //快乐值最大直接更新
        if(h_cur > h_max)
        {
            day = i + 1;
            h_max = h_cur;
            s_min = s_cur;
        }
        //快乐值相同,但羞耻度较小,也更新
        else if(h_cur == h_max && s_cur < s_min) 
        {
            day = i + 1;
            s_min = s_cur;
        }
    }
    cout << day << endl;
    return 0;
}

ps: 注意累加变量类型用 long/long long, 不然会溢出, 另外题目要求就是找快乐值最大的, 即使羞耻度也很大.

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值