本题的数组内的元素没有任何顺序,并且分成两部分数组的长度并不知道,也不一定相等,并且移动的元素未知,该元素所到的地方也未知
所以本菜鸟看到这题真的是一点思路也没有,看了y总代码又被这精妙的思路秀到了
利用哈希表+前缀和 成功解决本题目,真的十分精巧。
y总将这个分为三大类情况:
1、未移动元素前,前边i个元素和是总元素和的一半
2、未移动元素前,后边i个元素和是总元素和的一半
3、移动元素前,前边i个元素和减去总元素和的一半是某个元素(aj)的值(aj是将要从前边移动到后边的元素)
好好学习这个思路吧!!
代码:
#include<iostream>
#include<algorithm>
#include<unordered_set>
using namespace std;
const int N=1e5+10;
typedef long long ll;
ll sum[N];
int n;
ll a[N];
ll b[N];
bool check(ll w[]){
unordered_set<ll>S;
S.insert(0);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+w[i];
if(sum[n]%2!=0){
return false;
//如果和为奇数单独拿出来尽心特判
}
for(int i=1;i<=n;i++){
S.insert(w[i]);
if(S.count(sum[i]-sum[n]/2)){
return true;
}
}
return false;
}
int main(){
int m;
cin>>m;
while(m--){
cin>>n;
for(int i=1,j=n;i<=n,j>=1;i++,j--){
cin>>a[i];
b[j]=a[i];
}
if(check(a)||check(b)){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
代码中需要注意a,b数组内元素的最大值是1e9,所以需要用long long 元素存储,不可以用int
因为这个找了好长时间的bug 什么时候用 long long 和int 一定要分清
代码中当s[n]是奇数值时一定要单独拿出来进行特判否则,s[n]/2下取整会出现结果错误
收获:
本题学习这种做题思路以及map,unordered_map和set,unordered_set这几种迭代器的用法
详情可见: 几种用法