链接:https://www.nowcoder.com/acm/contest/77/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给你a,b和n个数p[i],问你如何分配这n个数给A,B集合,并且满足:
若x在集合A中,则a-x必须也在集合A中。
若x在集合B中,则b-x必须也在集合B中。
输入描述:
第一行 三个数 n a b 1<=n<=1e5 1<=a,b<=1e9 第二行 n个数 p1 p2 p3...pn 1<=pi<=1e9
输出描述:
如果可以恰好分开就输出第一行 YES 然后第二行输出 n个数 分别代表pi 是哪个集合的 0 代表是A集合 1代表是B 集合 不行就输出NO 放在哪个集合都可以的时候优先放B
示例1
输入
4 5 9 2 3 4 5
输出
YES 0 0 1 1
示例2
输入
3 3 4 1 2 4
输出
NO
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<vector>
using namespace std;
#define LL long long
#define inf 0x3ffffffff
const int N=100005;
int s[N],far[N];
map<int,int>mpp;
int finf(int a)
{
return far[a]==a?a:far[a]=finf(far[a]);
}
void uion(int a,int b)
{
int fa=finf(a);
int fb=finf(b);
if(fa!=fb) far[fb]=fa;
}
int main()
{
int n,a,b,fa,fb;
while(~scanf("%d%d%d",&n,&a,&b))
{
mpp.clear();
for(int i=0;i<=n+1;i++)//初始化
far[i]=i;
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
mpp[s[i]]=i;
}
//这个for循环将数组分为两组或者一组
for(int i=1;i<=n;i++)
{
if(mpp[b-s[i]]) uion(i,mpp[b-s[i]]);
else uion(i,0);//第一组
if(mpp[a-s[i]]) uion(i,mpp[a-s[i]]);
else uion(i,n+1);//第二组
}
fa=finf(0);
fb=finf(n+1);
if(fa==fb)//如果两组的根节点相同,那么说明有一个或多个数需要同时在两个数组里
{
printf("NO\n");
continue;
}
else
{
printf("YES\n");
for(int i=1;i<=n;i++)
{
if(i!=1) printf(" ");
if(fa==finf(i)) printf("0");
else printf("1");
}
printf("\n");
}
}
}
//3 4 8
//1 3 5
//4 5 9
//2 3 4 5
//3 3 8
//1 2 5
1633

被折叠的 条评论
为什么被折叠?



