小X分集合 【map】+【模拟】

26 篇文章 0 订阅

小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 。看这组数据,你就会明白为什么我要那样写了。*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值