题目链接:http://codeforces.com/problemset/problem/808/D
题意:问能不能通过交换不超过两个元素的位置使得原数组变成能分成前,后和相等的连续两部分;
注意这里只能交换一次!!!
思路:若存在某段前缀和 sum1[i] + x = ans/2 其中 x 为[ 0, i ] 外的某个元素 或者后缀和 sum2[i] + x = ans/2 其中 x 为 [ i, n-1 ] 外的某个元素;
则为 "YES" ,否则为 "NO" ;
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <map> 4 #define ll long long 5 using namespace std; 6 7 const int MAXN = 1e5+10; 8 map<ll, int> mp1, mp2; 9 int a[MAXN]; 10 11 int main(void){ 12 int n; 13 ll ans=0; 14 scanf("%d", &n); 15 for(int i=0; i<n; i++){ 16 scanf("%d", &a[i]); 17 ans += a[i]; 18 mp1[a[i]]++; 19 mp2[a[i]]++; 20 } 21 if(ans&1){ 22 cout << "NO" << endl; 23 return 0; 24 } 25 ans >>= 1; 26 ll num1=0, num2=0; 27 for(int i=0; i<n; i++){ 28 if(mp1[ans-num1] > 0){ 29 cout << "YES" << endl; 30 return 0; 31 } 32 num1 += a[i]; 33 mp1[a[i]]--; 34 } 35 for(int i=n-1; i>=0; i--){ 36 if(mp2[ans-num2] > 0){ 37 cout << "YES" << endl; 38 return 0; 39 } 40 num2 += a[i]; 41 mp2[a[i]]--; 42 } 43 cout << "NO" << endl; 44 return 0; 45 }