小X有n个互不相同的整数: p1,p2,…,pnp1,p2,…,pn 。他想把这些整数分到两个集合A和B里边。但是要符合下面两个条件。
・ 如果x属于A,那么a-x也肯定属于A。
・ 如果x属于B,那么b-x也肯定属于B。
判断一下是否存在一种方案来分配这些数字到集合A,B中。
注意:如果一个集合为空也是可以的。
Input
单组测试数据。
第一行有三个整数n,a,b (1≤n≤10^5; 1≤a,b≤10^9)。
第二行有n个不一样的整数 p1,p2,…,pn (1≤pi≤10^9).
Output
如果可行,那么输出YES,否则输出NO。
Sample Input
样例输入1
4 5 9
2 3 4 5
Sample Output
样例输出1
YES
一眼看上去就是用map 标记。。【ps果然有坑】
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<iostream>
#define LL long long
using namespace std;
const int MAXN= 1e5+100;
const int MAXM= 1e8;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){ if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}
return x*f;
}
/*------------------------------------*/
int arr[MAXN];
map<int ,int >mp[3];
map<int ,int >:: iterator it;
int main(){
int n,a,b;
mp[1].clear();
mp[2].clear();
string s="";
scanf("%d%d%d",&n,&a,&b);
int flag=1;
for(int i=0;i<n;i++) {
arr[i]=read();
if(arr[i]>=a&&arr[i]>=b) {flag=0;s="NO";}
mp[1][arr[i]]=1;
mp[2][arr[i]]=1;
}
if(!flag) cout<<s<<endl;
else{
s="";
for(int i=0;i<n;i++){
if(mp[1][arr[i]]&&mp[1][b-arr[i]]) {mp[1][arr[i]]=mp[1][b-arr[i]]=0;}
if(mp[1][arr[i]]&&mp[1][a-arr[i]]) {mp[1][arr[i]]=mp[1][a-arr[i]]=0;}
}
for( it=mp[1].begin();it!=mp[1].end();it++){
if(it->second==1) {s+="NO";break;}
}
if(s=="NO"){
s="";
for(int i=0;i<n;i++){
if(mp[2][arr[i]]&&mp[2][a-arr[i]]) {mp[2][arr[i]]=mp[2][a-arr[i]]=0;}
if(mp[2][arr[i]]&&mp[2][b-arr[i]]) {mp[2][arr[i]]=mp[2][b-arr[i]]=0;}
}
for( it=mp[2].begin();it!=mp[2].end();it++){
if(it->second==1) {s+="NO";break;}
}
}
if(s.empty()) s="YES";
cout<<s<<endl;
}
return 0;
}
/* 注意中间枚举部分,两部分是不一样的,第一次先往a集合放,然后放b集合, 第二次是先往b集合放,然后向a集合放。 为什么这样了? 因为我是wa到17组数据,想着肯定有特殊情况,就造了半天数据才测出来,样例 3 4 6 2 3 4 。看这组数据,你就会明白为什么我要那样写了。*/