HDU 5191 Building Blocks(枚举)

来源:互联网 发布:法国人 知乎 编辑:程序博客网 时间:2024/05/17 00:17

Building Blocks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1464    Accepted Submission(s): 311


Problem Description
After enjoying the movie,LeLe went home alone. LeLe decided to build blocks.
LeLe has already built n piles. He wants to move some blocks to make W consecutive piles with exactly the same height H.

LeLe already put all of his blocks in these piles, which means he can not add any blocks into them. Besides, he can move a block from one pile to another or a new one,but not the position betweens two piles already exists.For instance,after one move,"3 2 3" can become "2 2 4" or "3 2 2 1",but not "3 1 1 3".

You are request to calculate the minimum blocks should LeLe move.
 

Input
There are multiple test cases, about 100 cases.

The first line of input contains three integers n,W,H(1n,W,H50000).n indicate n piles blocks.

For the next line ,there are n integers A1,A2,A3,,An indicate the height of each piles. (1Ai50000)

The height of a block is 1.
 

Output
Output the minimum number of blocks should LeLe move.

If there is no solution, output "-1" (without quotes).
 

Sample Input
4 3 21 2 3 54 4 41 2 3 4
 

Sample Output
1-1
问题描述
看完电影后,乐乐回家玩起了积木。他已经搭好了n堆积木,他想通过调整积木,使得其中有连续W堆积木具有相同的高度,同时他希望高度恰好为H。乐乐的积木都这了,也就是说不能添加新的积木,只能移动现有的积木。他可以把一个积木从一堆移动到另一堆或者新的一堆,但是不能移动到两堆之间。比如,一次移动之后,"3 2 3" 可以变成 "2 2 4" 或者 "3 2 2 1",但是不能变成"3 1 1 3".请你帮他算算,需要移动的最少积木数。
输入描述
有多组测试数据,大约100组。第一行三个整数,nWHn表示有多少堆积木。第二行n个元素,表示这n座积木的高度。所有数据的范围[1,50000];
输出描述
输出最少需要移动的积木数,如果无法完成输出-1。
在长度为1-3*w的长度上不断的取1~w的区间,在1-w的区间长度上求这些积木的高度高于h部分的和,和 低于h部分的和,这俩值中最大的那一个就是这段区间上需要移动的积木数,枚举所有的区间,最后结果就是这些数中的最小值
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>#define N 50010#define inf 0x3f3f3f3fusing namespace std;int a[N*3];int main(){    int w,n,h;    while(~scanf("%d%d%d",&n,&w,&h))    {        int sum=0;        memset(a,0,sizeof(a));        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i+w]);            sum+=a[i+w];        }        if(sum<w*h)        {            printf("-1\n");            continue;        }        int  ans=inf;                int sum1=0;              //1~w都为0,所以高于h部分的和为0        int sum2=w*h;            //低于h部分的和为h*w;        for(int i=w+1; i<=n+w*2; i++)        {            if(a[i-w]>h)         //从第w+1 开始枚举,不断的去掉最左面侧的积木高度                sum1-=a[i-w]-h;               else sum2-=h-a[i-w];            if(a[i]>h)            //为维持区间长度为w 在从最右侧加入新的积木数                sum1+=a[i]-h;            else                sum2+=h-a[i];            ans=min(ans,max(sum1,sum2));             }        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击