• Educational Codeforces Round 21 Problem D(Codeforces 808D)


    Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into two non-empty consecutive parts (the prefix and the suffix) so that the sum of all elements in the first part equals to the sum of elements in the second part. It is not always possible, so Vasya will move some element before dividing the array (Vasya will erase some element and insert it into an arbitrary position).

    Inserting an element in the same position he was erased from is also considered moving.

    Can Vasya divide the array after choosing the right element to move and its new position?

    Input

    The first line contains single integer n (1 ≤ n ≤ 100000) — the size of the array.

    The second line contains n integers a1, a2... an (1 ≤ ai ≤ 109) — the elements of the array.

    Output

    Print YES if Vasya can divide the array after moving one element. Otherwise print NO.

    Examples
    input
    3
    1 3 2
    output
    YES
    input
    5
    1 2 3 4 5
    output
    NO
    input
    5
    2 2 3 4 5
    output
    YES
    Note

    In the first example Vasya can move the second element to the end of the array.

    In the second example no move can make the division possible.

    In the third example Vasya can move the fourth element by one position to the left.


      我很好奇,我和同学内部玩Virtual Contest的时候有个人读不懂前三题,偏偏这道题我读错了,他读懂。最后看到题目描述最后一句话中的element,单数!才发现只能移动一个,内心极其崩溃绝望,但还是在10分钟赶出了程序。

      题目大意是说,给定一个数列,将一个数移动到另一个位置或者什么都不做,是否使得这个数列能被划分成2个部分。

      记两个sum,一个是左边求和的sum,还有一个是另一边求和的sum。最开始左边的sum为0,右边的和为整个数列的和,然后依次将下一个数添加进左边,在右边删去这个数并修改sum,再判断两个sum是否相等,如果相等就可以简单地puts("YES"),然后exit(0)了,如果不相等,就判断差是否为奇数,如果不是就看看和大的那一边存不存在值为差的一半的数(存在就把它拿到小的那一边,就可以使和相等了),如果存在就输出YES退出程序。循环结束了,直接输NO就好了。

      至于判断这个数存不存在,交给可重集就好了。

    Code

      1 /**
      2  * Codeforces
      3  * Problem#808D
      4  * Accepted
      5  * Time:15ms
      6  * Memory:0k
      7  */
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<ctime>
     11 #include<cctype>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<fstream>
     15 #include<sstream>
     16 #include<algorithm>
     17 #include<map>
     18 #include<set>
     19 #include<stack>
     20 #include<queue>
     21 #include<vector>
     22 #include<stack>
     23 using namespace std;
     24 typedef bool boolean;
     25 #define inf 0xfffffff
     26 #define smin(a, b) a = min(a, b)
     27 #define smax(a, b) a = max(a, b)
     28 #define max3(a, b, c) max(a, max(b, c))
     29 #define min3(a, b, c) min(a, min(b, c))
     30 template<typename T>
     31 inline boolean readInteger(T& u){
     32     char x;
     33     int aFlag = 1;
     34     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     35     if(x == -1) {
     36         ungetc(x, stdin);
     37         return false;
     38     }
     39     if(x == '-'){
     40         x = getchar();
     41         aFlag = -1;
     42     }
     43     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     44     ungetc(x, stdin);
     45     u *= aFlag;
     46     return true;
     47 }
     48 
     49 #define LL long long
     50 
     51 int n;
     52 int* a;
     53 LL sum = 0;
     54 multiset<LL> s;
     55 multiset<LL> s1, s2; 
     56 
     57 inline void init() {
     58     readInteger(n);
     59     a = new int[(const int)(n + 1)];
     60     for(int i = 1; i <= n; i++) {
     61         readInteger(a[i]);
     62         sum += a[i];
     63         s.insert(sum);
     64         s2.insert(a[i]);
     65     }
     66 }
     67 
     68 LL sum1 = 0, sum2 = 0;
     69 
     70 inline void solve() {
     71     if(sum & 1) {
     72         puts("NO");
     73         return;
     74     }
     75     sum2 = sum;
     76     sum /= 2;
     77     if(s.count(sum)) {
     78         puts("YES");
     79         return;
     80     }
     81     for(int i = 1; i <= n; i++) {
     82         if(sum1 > sum2) {
     83             LL temp = sum1 - sum2;
     84             if((temp & 1) == 0 && s1.count(temp / 2)) {
     85                 puts("YES");
     86                 return;
     87             }
     88         } else {
     89             LL temp = sum2 - sum1;
     90             if((temp & 1) == 0 && s2.count(temp / 2)) {
     91                 puts("YES");
     92                 return;
     93             }
     94         }
     95         sum1 += a[i], sum2 -= a[i];
     96         s1.insert(a[i]), s2.erase(s2.find(a[i]));
     97     }
     98     puts("NO");
     99 }
    100 
    101 int main() {
    102     init();
    103     solve();
    104     return 0;
    105 }
  • 相关阅读:
    Context都没弄明白,还怎么做Android开发?
    Android中Drawable分类汇总
    查找首个非重复字符
    七个对我最好的职业建议(译文)
    Android:最全面的 Webview 详解
    Android开发之微信底部菜单栏实现的几种方法汇总
    android 底部菜单栏实现(转)
    Android实现顶部底部双导航界面功能
    Android BottomNavigationBar底部导航控制器的使用
    Android底部导航栏的四种实现
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6936974.html
Copyright © 2020-2023  润新知