HDU—— 5159 Building Blocks

题意:n堆积木,通过调整使得其中有连续W堆积木具有相同的高度,同时高度恰好为H,不能添加新的积木,只能移动现有的积木。可以把一个积木从一堆移动到另一堆或者新的一堆,但是不能移动到两堆之间,比如,一次移动之后,"3 2 3" 可以变成 "2 2 4" 或者 "3 2 2 1",但是不能变成"3 1 1 3"。

解题思路:首先记录n个数值的总和,然后每次以w长度对数组进行遍历,切每次对w区间长度内的数值进行处理,将每个大于H的A[i]与H的差值累加赋给t1,将每个小于H的A[i]与H的差值累加赋给t2,然后将t1,t2中较大的值与上次的ans比较取出最小值赋给ans,ans表示该w长度内满足条件时所需移动的次数,然后往下移动即t1或t2中移除一个a[i-w],然后添加一个a[i],最后输出ans即可。

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define INT_MAX 1e9+10
typedef long long LL;
int n,w,h;
int a[200000];

int main()
{
    //freopen("input.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&w,&h))
    {
        fill(a,a+200000,0);
        LL sum=0,t1 = 0,t2 = 0;//t1代表高度超过H的总和,t2高度小于H的总和,sum表示所有输入a[i]值的总和
        int i = 0;
        for(;i<w; i++)//数组a[i]的前端增加w个0
        {
            a[i] = a[i]-h;//a[i]-h表示每个a[i]值与h的差值,并将该差值赋给a[i]
            t2 +=-a[i];//将差值小于0的累加赋给t2保存
        }
        for(;i<n+w; i++)
        {
            scanf("%d",&a[i]);
            sum +=a[i];
            a[i] = a[i]-h;//将每个a[i]替换成a[i]-h的差值
        }
        for(;i<n+2*w; i++)
        a[i] = a[i]-h;
        LL ans = INT_MAX;
        ans = max(t1,t2);//将t1、t2中的最大值赋给ans,ans表示每次移动的次数,
        if(sum < w*h) printf("-1\n");//sum小于w*h直接输出-1
        else                         //否则遍历后边的区间
        {
            for(int j = w; j<n+2*w; j++)
            {
                if(a[j-w] > 0) t1 -=a[j-w];//t1移除前面一个a[i]值
                else t2 +=a[j-w];//t2移除后面一个a[i]值
                if(a[j] > 0) t1 +=a[j];//t1往后添加一个a[i]值
                else t2 +=-a[j];//t2往后添加一个a[i]值
                ans = min(ans,max(t1,t2));//每次找出最小值赋给ans
            }
            printf("%I64d\n",ans);
        }
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值