解题思路:
首先我们先假设存在一种合理的方案,则有 对于任一个数x,肯定在a,b集合中的一个。同时如果方案合理,最后的结果a,b集合中的元素没有交集。
1.对于一个数x,如果a-x不存在,则x肯定在b分组中(假定分组成立),则把x和b分组并起来;如果同时b-x也不存在的话,则再把x和a分组并起来,此时a和b分组被并了起来,显然这种方案不合理。
2.对于一个数x,如果a-x存在,则把x和a-x对应的下标并起来,此时并不能说明x属于集合a,因为可能存在N=2,a=8,b=20,4,16,这样的数据,只有当b-x不存在时,才把x和a的下标并起来。
3,如果b-x也存在时,就把x和b-x也的下标也并起来,此时如果x!=a-x!=b-x时,说明a和b集合公用x,即这种方案a和b被并起来,这种方案也不合理。此时如果x==a-x!=b-x,显然应分组为b,当然特例就是a和b相等,此时任何分组都可以。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define pi acos(-1)
#define N 100005
int f[N],num[N];
map <int ,int> mp;
int findd(int x)
{
return x!=f[x]?f[x]=findd(f[x]):f[x];
}
void mergee(int x,int y)
{
int fx=findd(x);
int fy=findd(y);
if(fx!=fy)
f[fx]=fy;
return ;
}
int main()
{
int n,A,B;
while(~scanf("%d%d%d",&n,&A,&B))
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
mp[num[i]]=i;
}
for(int i=1;i<=n+2;i++)
f[i]=i;
for(int i=1;i<=n;i++)
{
if(mp[A-num[i]]) mergee(i,mp[A-num[i]]);
else mergee(i,n+2);
if(mp[B-num[i]]) mergee(i,mp[B-num[i]]);
else mergee(i,n+1);
}
int x=findd(n+1);
int y=findd(n+2);
if(x==y) puts("NO");
else
{
puts("YES");
for(int i=1;i<=n;i++)
{
if(findd(i)==findd(n+1)) printf("0 ");
else printf("1 ");
}
printf("\n");
}
}
return 0;
}