• D. Array Division


    http://codeforces.com/contest/808/problem/D

    一开始是没什么想法的,然后回顾下自己想题的思路,慢慢就想出来了。首先要找到是否有这样的一个位置使得:

    前缀和 == 后缀和,可以二分来求。

    然后可以这样想,如果对于每一个数字,我都去移动一下,每个位置都试一下,复杂度多少?显然不能承受。

    然后优化下这个思路,有了一点思路,优化到极致,看看能不能过,不能过就换思路吧。一般来说,每一个位置都试一下,是很没必要的。一般都是有一个位置是最优的。

    这个位置就是放在最前或者放在最后。可以这样去想。

    如果原来的数组,是不存在这样的位置的,那么移动a[i]到某一个位置后,存在了这样的位置。那么肯定是把这个数字移动去了前缀和的贡献哪里(后缀和同理),因为不是移动到前缀和哪里,就相当于没移。

    所以把它移动到第1位,前缀和就肯定包含它了。

    最后还是被hack,细节写歪了

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    const int maxn = 1000000 + 20;
    int n;
    int a[maxn];
    LL sum[maxn];
    LL nowDel;
    LL ask(int pos) {
        if (pos < nowDel) {
            return sum[pos] - a[pos] + a[nowDel];
        } else return sum[pos];
    }
    LL ask2(int pos) {
        if (pos >= nowDel) {
            return sum[pos] - a[nowDel] + a[pos + 1];
        } else return sum[pos];
    }
    bool tofind(int which) {
        int be = 2, en = n;
        while (be <= en) {
            int mid = (be + en) >> 1;
            LL lef;
            if (which == 1) lef = ask(mid - 1);
            else lef = ask2(mid - 1);
            LL rig = sum[n] - lef;
            if (lef < rig) be = mid + 1;
            else en = mid - 1;
        }
        LL lef;
        if (which == 1) lef = ask(en);
        else lef = ask2(en);
        return lef * 2 == sum[n];
    }
    void work() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
    //    nowDel = 2;
    //    tofind(2);
        for (int i = 1; i <= n; ++i) {
            nowDel = i;
            if (tofind(1)) {
                printf("YES
    ");
                return;
            }
            if (tofind(2)) {
                printf("YES
    ");
                return;
            }
        }
        printf("NO
    ");
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    设置圆角代码
    队列组的简单使用
    多线程的延时执行和一次性代码
    GCD线程间的通信
    GCD"牛逼的中枢调度器"
    线程间的通信
    KVO运行时
    iOS Programming Localization 本地化
    iOS Programming State Restoration 状态存储
    如何安装sql server2005 windows 8
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6868471.html
Copyright © 2020-2023  润新知