题意:
给你一串数字,问你能否从其中任意选出一个数插入任意一个位置,使得这个数前后两部分和相等,若能,输出YES,不能则NO。
思路:
判断总和能否对半分,不能则NO,遍历每一个数字,再用二分查找前缀和数组,看能否使得sum[x]-a[i]==d,这只是一种情况,表示将当前元素向后插,还有一种情况sum[x]+a[i]==d代表向前插入,所以要二分两次。
手写二分:
#include <bits/stdc++.h>
#define me(x,y) memset(x,y,sizeof(x))
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define ps(x) printf("%s",x)
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<y?x:y)
#define sum(x,y) (x+y)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100005;
int n;
int a[maxn];
ll sum[maxn];
int main()
{
sd(n);
for(int i=0;i<n;i++) {
sd(a[i]);
if(i==0) sum[i]=a[i];
else sum[i]=sum[i-1]+a[i];
}
if(sum[n-1]%2) {
ps("NO");
return 0;
}
ll d=sum[n-1]>>1;
for(int i=0;i<n;i++) {
int l=0,r=n-1,mid;
while(l<=r) {
mid=(l+r)>>1;
if(sum[mid]-a[i]==d) {
if(mid>=i) {
ps("YES");
return 0;
}
else break;
}
if(sum[mid]-a[i]>d) r=mid-1;
else l=mid+1;
}
l=0;r=n-1;
while(l<=r) {
mid=(l+r)>>1;
if(sum[mid]+a[i]==d) {
if(mid<i) {
ps("YES");
return 0;
}
else break;
}
if(sum[mid]+a[i]>d) r=mid-1;
else l=mid+1;
}
}
ps("NO");
return 0;
}
STL lower_bound :
#include <bits/stdc++.h>
#define me(x,y) memset(x,y,sizeof(x))
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define ps(x) printf("%s",x)
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<y?x:y)
#define sum(x,y) (x+y)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100005;
int n;
int a[maxn];
ll sum[maxn];
int main()
{
sd(n);
for(int i=0;i<n;i++) {
sd(a[i]);
if(i==0) sum[i]=a[i];
else sum[i]=sum[i-1]+a[i];
}
if(sum[n-1]%2) {
ps("NO");
return 0;
}
ll d=sum[n-1]>>1;
for(int i=0;i<n;i++) {
int l=0,r=n-1,mid;
ll *j=lower_bound(sum,sum+n,a[i]+d);
if(*j && sum[j-sum]==a[i]+d && j-sum>=i) {
ps("YES");
return 0;
}
l=0;r=n-1;
j=lower_bound(sum,sum+n,d-a[i]);
if(*j && sum[j-sum]==d-a[i] && j-sum<i) {
ps("YES");
return 0;
}
}
ps("NO");
return 0;
}