HDU 5191 Building Blocks

题目链接:

hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5191

bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=572&pid=1002

题解:

要在原始的n堆前面扩展w个空堆,同时在原始n堆后面扩展w个空堆,然后对[0,w+n+w)这个区间考虑所有的长度为w的子区间,计算出需要移动的方块数,更新答案。

代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int maxn = 50000+10;
10 
11 int n;
12 LL w, h;
13 int arr[maxn*3];
14 
15 void init() {
16     memset(arr, 0, sizeof(arr));
17 }
18 
19 int main() {
20     while (scanf("%d%lld%lld", &n, &w,&h) == 3 && n) {
21         init();
22         LL sum = 0;
23         for (int i = 0; i < n; i++) {
24             scanf("%d", arr + i+w);
25             sum += arr[i+w];
26         }
27         if (sum < w*h) {
28             printf("-1\n");
29             continue;
30         }
31         //cntf:总共需要填入多少个方块,cntz:总共需要移出多少个方块,cnt保存连续w个的初始和
32         LL cntz = 0,cntf=w*h, cnt = 0;
33         LL ans = w*h;
34         for (int i = w; i < 2*w+n; i++) {
35             //计算新窗口的cntz,cntf,cnt;
36             if (arr[i - w] - h>0) cntz -= (arr[i - w] - h);
37             else cntf -= (h - arr[i - w]);
38             cnt -= arr[i - w];
39             if (arr[i] - h > 0) cntz += arr[i] - h;
40             else cntf += h - arr[i];
41             cnt += arr[i];
42             
43             LL tmp;
44             if (w*h > cnt) tmp =cntf;
45             else tmp = cntz;
46 
47             ans = min(ans, tmp);
48         }
49 
50         printf("%lld\n", ans);
51     }
52     return 0;
53 }

 

posted @ 2016-04-23 21:16  fenicnn  阅读(122)  评论(0编辑  收藏  举报