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

 

转载于:https://www.cnblogs.com/geloutingyu/p/6875613.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值