Array Division CodeForces - 808D (构造+实现)
Posted qieqiemin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Array Division 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
3
1 3 2
YES
5
1 2 3 4 5
NO
5
2 2 3 4 5
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.
题意:给你一个包含N个数的数组,让你把这N个数分成两个非空的集合,使这两个集合的sum和相等。
如果能就输出yes,否就no
思路: 首先根据全部元素的sum和如果为奇数,直接输出NO。
否则,进入下面的操作。
创建两个map,即m1和m2
一个额外变量 LL temp=0ll,用来记录划分的第一个集合的sum值
m2代表第一个集合中存在的元素数量,
m1代表未加入到第一个集合中的元素的存在数量。
扫一遍,把元素都加入到一个m1中,
然后从1~n循环遍历数组,
sum/=2ll; // sum就代表了平分后每一个集合要等于的数值。
每一次执行
temp+=a[i];// 把a[i]加入到集合中
m1[a[i]] --; // 从剩下的数集合中删除
if(m1[sum-temp])
{
cout<<"YES"<<endl;
}
// 即 如果剩下的元素中存在 sum-temp这个数,那么直接把那个数再加入到集合中就可以完成平分,所以使yes
if(m2[temp-sum])
{
printf("YES
");
return 0;
}
// 即如果第一个集合中存在temp-sum这个元素,那么删除它就可以实现平分。
都没有的话,最后输出no
细节见我的AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), ‘ ‘, sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) using namespace std; typedef long long ll; inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ int n; int a[maxn]; ll sum=0ll; map<ll,ll> m1,m2; void init() { m1.clear(); m2.clear(); } int main() { gg(n); repd(i,1,n) { gg(a[i]); sum+=1ll*a[i]; m1[a[i]]++; } if(sum&1) { // odd printf("NO "); return 0; } sum/=2ll; ll temp=0ll; repd(i,1,n) { temp+=a[i]; m1[a[i]]--;// right delete m2[a[i]]++;// left plus if(m1[sum-temp]) { printf("YES "); return 0; } if(m2[temp-sum]) { printf("YES "); return 0; } } printf("NO "); return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘ ‘); if (ch == ‘-‘) { *p = -(getchar() - ‘0‘); while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 - ch + ‘0‘; } } else { *p = ch - ‘0‘; while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 + ch - ‘0‘; } } }
以上是关于Array Division CodeForces - 808D (构造+实现)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces-808D Array Division (multiset 折半???)
[Codeforces Round #680] C. Division
Codeforces 1106CLunar New Year and Number Division
Codeforces Round #598 (Div. 3) E. Yet Another Division Into Teams dp
Codeforces Round #661 (Div. 3) E2. Weights Division (hard version)
Codeforces Round #661 (Div. 3) E2. Weights Division (hard version)