tracker2026.02.07相邻的糖果 贪心+双指针

相邻的糖果


这个题其实就是一个贪心题,求任何m个相邻的盒子内糖果的数目不能超过x个。
那么我们可以想,如果这个盒子里面的糖果的数目和超过了x个,那肯定是要把超出的部分都减掉。
而前面的盒子又会跟后面的盒子又组成新的一组。所以减掉后面的糖果会让下一组的总数减少,所以我们肯定是优先减掉靠后的糖果。
我在这里实现的时候就是说如果sum>x,就相应的减掉sum-x个。因为如果本身不大于x个,而加入新的糖果之后,整体大于x,那么新进来的盒子肯定是够减的。
这里用双指针维护,如果不够m个,那就是右指针右移。当算完了这一组m个之后,左指针右移,这样下一次循环的时候就会判断为不够m个右指针继续右移。
纯享版

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e6+100;
int a[N];
int n,m,x;
signed main()
{
    cin>>n>>m>>x;
    for(int i = 1 ; i <= n ; ++i)cin>>a[i];
    int l = 0,r = 0;
    int sum = 0,cnt = 0;
    while(r < n)
    {
        while(r-l+1 < m){
            r++;
            sum+=a[r];
            if(sum > x){
                int res = sum-x;
                cnt += res;a[r]-=res;sum-=res;
            }
        }
        sum-=a[l];l++;
    }
    cout<<cnt<<endl;
    return 0;
}

测试+备注版

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e6+100;
int a[N];
int n,m,x;
signed main()
{
    cin>>n>>m>>x;
    for(int i = 1 ; i <= n ; ++i)cin>>a[i];
    int l = 0,r = 0;
    int sum = 0,cnt = 0;
    //sum表示目前手里有的,cnt表示需要拿掉的糖果
    while(r < n)
    {
        while(r-l+1 < m){
            //如果不够的话就往后加
//             cout<<r<<" "<<l<<endl;
            r++;
            sum+=a[r];
            if(sum > x){
                int res = sum-x;//超出的部分
//                 cout<<r<<" "<<res<<endl;
//                 cout<<sum<<" "<<x<<" "<<res<<endl;
                cnt += res;a[r]-=res;sum-=res;
//                 累加超出的部分,并且让当前的减掉
            }
        }
//         cout<<r<<" "<<l<<endl;
        sum-=a[l];l++;
//         左指针右移并且减掉相应贡献
    }
//     cout<<r<<" "<<l<<endl;
//     for(int i = 1 ; i <= n ; ++i)
//         cout<<a[i]<<" \n"[i == n];
//     cout<<r<<" "<<l<<endl;
    cout<<cnt<<endl;
    return 0;
}
posted on 2026-02-10 22:11  钟一一  阅读(22)  评论(0)    收藏  举报