cf808D(xjb)

题目链接: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 }
View Code

 

posted @ 2017-05-18 21:10  geloutingyu  阅读(175)  评论(0编辑  收藏  举报