刚刚结束的 cf D 题求 hack
  • 板块学术版
  • 楼主Acfboy
  • 当前回复3
  • 已保存回复3
  • 发布时间2021/5/16 18:05
  • 上次更新2023/11/4 23:10:28
查看原帖
刚刚结束的 cf D 题求 hack
40318
Acfboy楼主2021/5/16 18:05

正解似乎是 dp, 但是我写了贪心,求 hack。

思想是找到一块向两边拓展着移动。

#include <cstdio>
#include <cmath>
#include <algorithm>
const int N = 5005;
int n, a[N], t, an[N], ans = 0x3f3f3f3f, cnt;
int findNext(int *a, int x) {
    while(x <= n && a[x] == 0) x++;
    if(x > n) x = -1;
    return x;
}
void findBlock(int x, int &l, int &r) {
    while(x <= n && a[x] == 0) x++;
    l = x;
    while(x <= n && a[x] == 1) x++;
    r = x-1;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) 
        scanf("%d", &a[i]);
    int l, r;
    findBlock(0, l, r);
    // printf("%d %d\n", l, r);
    for( ; l <= n && r <= n; findBlock(r+1, l, r)) 
        for(int j = 1, tot = 0; tot < r-l+1; j++) {
            if(l-j+1 >= 1 && a[l-j+1] == 0 && an[l-j+1] == 0) an[l-j+1] = 1, tot ++;
            if(tot == r-l+1) break;
            if(r+j-1 <= n && a[r+j-1] == 0 && an[r+j-1] == 0) an[r+j-1] = 1, tot ++;
        }
    // for(int i = 1; i <= n; i++) printf("%d ", an[i]);
    int i1 = findNext(an, 1), i2 = findNext(a, 1);
    for( ; i1 != -1 && i2 != -1; i1 = findNext(an, i1+1), i2 = findNext(a, i2+1))
        t += std::abs(i2 - i1);
    printf("%d", t);
    return 0;
}
2021/5/16 18:05
加载中...