集合问题

题号:NC15167
时间限制:C/C++ 1秒,其他语言2秒
空间限制: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
/*
*@Author: GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<list>
#include<set>
#include<iomanip>
#include<cstring>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cassert>
#include<sstream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
const int MAXN = 305;
const int INF = 0x3f3f3f3f;
const int N=5e4+7;
const int maxn=1e5+5;
const double EPS=1e-10;
const double Pi=3.1415926535897;
//inline double max(double a,double b){
// return a>b?a:b;
//}
//inline double min(double a,double b){
// return a<b?a:b;
//}
int xd[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int yd[8] = {1, 0, -1, 0, -1, 1, -1, 1};
//void Fire(){
// queue<node> p;
// p.push({fx,fy,0});
// memset(fire, -1, sizeof(fire));
// fire[fx][fy]=0;
// while(!p.empty()){
// node temp=p.front();
// p.pop();
// for(int i=0;i<8;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m||fire[x][y]!=-1){
// continue;
// }
// fire[x][y]=temp.val+1;
// p.push({x,y,temp.val+1});
// }
// }
//}
//int bfs(){
// queue<node> p;
// memset(vis, 0, sizeof(vis));
// p.push({sx,sy,0});
// while (!p.empty()) {
// node temp=p.front();
// vis[temp.x][temp.y]=1;
// p.pop();
// for(int i=0;i<4;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m) continue;
// if(x==ex&&y==ey&&temp.val+1<=fire[x][y]) return temp.val+1;
// if(vis[x][y]||temp.val+1>=fire[x][y]||a[x][y]=='#') continue;
// p.push({x,y,temp.val+1});
// }
// }
// return -1;
//}
//一维哈希
//int n;
//string s;
//int bas=131;
//typedef unsigned long long ull;
//const ull mod1=100001651;
//ull a[100010];
//ull Hash(string s){
// ll ans=0;
// for(int i=0;i<s.size();i++){
// ans*=bas;
// ans+=int(s[i]);
// ans%=mod1;
// }
// return ans;
//}
//二维哈希
//using lom=unsigned long long ;
//const lom bas1=131,bas2=233;
//const int M=505;
//int n,m;
//char a[M][M];
//lom _hash[M][M];
//lom p1[M],p2[M];
//
//
//void init(){
// p1[0]=1;
// p2[0]=1;
// for(int i=1;i<=505;i++){
// p1[i]=p1[i-1]*bas1;
// p2[i]=p2[i-1]*bas2;
//
// }
//}
//void Hash(){
// _hash[0][0]=_hash[0][1]=_hash[1][0]=0;
// for(int i=1;i<=n;i++){ //前缀和
// for(int j=1;j<=m;j++){
// _hash[i][j]=_hash[i][j-1]*bas1+a[i][j]-'a';
// }
// }
// for(int i=1;i<=n;i++){ //二维前缀和
// for(int j=1;j<=m;j++){
// _hash[i][j]+=_hash[i-1][j]*bas2;
// }
// }
//
//}
int n,a,b;
int fa[1000010];
int p[100010];
map<int,int> mp; //用map记录每个数字出现的位置
void init(){
for(int i=0;i<=n+1;i++){
fa[i]=i;
}
}
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void Union(int x,int y){
fa[find(x)]=find(y);
}
int main(){
cin>>n>>a>>b;
int maxn=0;
for(int i=1;i<=n;i++){
cin>>p[i];
mp[p[i]]=I; //记录位置
maxn=max(maxn,p[i]);
}
init();
if(max(a,b)<=maxn){ //要求pi必须大于1 所以最大的pi要小于ab的最大值
cout<<"NO"<<endl;
return 0;
}
for(int i=1;i<=n;i++){
if(mp[b-p[i]]) //先归于b集合
Union(i,mp[b-p[i]]);
else Union(i,0); //不符合b集合的条件 放于假a的集合
if(mp[a-p[i]])
Union(i,mp[a-p[i]]);
else Union(i,n+1); //假b集合
}
int A=find(0);
int B=find(n+1);
if(A==B) cout<<"NO"<<endl; //如果某个元素同时存在假a假b这不符合题意
else {
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){
if(find(i)==A) cout<<"0"<<" ";
else cout<<"1"<<" ";
}
}
}
/*
*@Author: GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<list>
#include<set>
#include<iomanip>
#include<cstring>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cassert>
#include<sstream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
const int MAXN = 305;
const int INF = 0x3f3f3f3f;
const int N=5e4+7;
const int maxn=1e5+5;
const double EPS=1e-10;
const double Pi=3.1415926535897;
//inline double max(double a,double b){
// return a>b?a:b;
//}
//inline double min(double a,double b){
// return a<b?a:b;
//}
int xd[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int yd[8] = {1, 0, -1, 0, -1, 1, -1, 1};
//void Fire(){
// queue<node> p;
// p.push({fx,fy,0});
// memset(fire, -1, sizeof(fire));
// fire[fx][fy]=0;
// while(!p.empty()){
// node temp=p.front();
// p.pop();
// for(int i=0;i<8;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m||fire[x][y]!=-1){
// continue;
// }
// fire[x][y]=temp.val+1;
// p.push({x,y,temp.val+1});
// }
// }
//}
//int bfs(){
// queue<node> p;
// memset(vis, 0, sizeof(vis));
// p.push({sx,sy,0});
// while (!p.empty()) {
// node temp=p.front();
// vis[temp.x][temp.y]=1;
// p.pop();
// for(int i=0;i<4;i++){
// int x=temp.x+xd[i];
// int y=temp.y+yd[i];
// if(x<0||x>=n||y<0||y>=m) continue;
// if(x==ex&&y==ey&&temp.val+1<=fire[x][y]) return temp.val+1;
// if(vis[x][y]||temp.val+1>=fire[x][y]||a[x][y]=='#') continue;
// p.push({x,y,temp.val+1});
// }
// }
// return -1;
//}
//一维哈希
//int n;
//string s;
//int bas=131;
//typedef unsigned long long ull;
//const ull mod1=100001651;
//ull a[100010];
//ull Hash(string s){
// ll ans=0;
// for(int i=0;i<s.size();i++){
// ans*=bas;
// ans+=int(s[i]);
// ans%=mod1;
// }
// return ans;
//}
//二维哈希
//using lom=unsigned long long ;
//const lom bas1=131,bas2=233;
//const int M=505;
//int n,m;
//char a[M][M];
//lom _hash[M][M];
//lom p1[M],p2[M];
//
//
//void init(){
// p1[0]=1;
// p2[0]=1;
// for(int i=1;i<=505;i++){
// p1[i]=p1[i-1]*bas1;
// p2[i]=p2[i-1]*bas2;
//
// }
//}
//void Hash(){
// _hash[0][0]=_hash[0][1]=_hash[1][0]=0;
// for(int i=1;i<=n;i++){ //前缀和
// for(int j=1;j<=m;j++){
// _hash[i][j]=_hash[i][j-1]*bas1+a[i][j]-'a';
// }
// }
// for(int i=1;i<=n;i++){ //二维前缀和
// for(int j=1;j<=m;j++){
// _hash[i][j]+=_hash[i-1][j]*bas2;
// }
// }
//
//}
int n,a,b;
int vis[100010];
int arr[100010];
int main()
{
cin>>n>>a>>b;
int flag=0;
for(int i=0;i<n;i++){
cin>>arr[i];
}
sort(arr,arr+n);
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
if(!vis[i]){
int a1=lower_bound(arr,arr+n,a-arr[i])-arr;
int b1=lower_bound(arr,arr+n,b-arr[i])-arr;
if(!vis[b1]&&arr[b1]+arr[i]==b) vis[i]=vis[b1]=1;
else if(!vis[a1]&&arr[a1]+arr[i]==a) vis[i]=vis[a1]=2;
}
}
for(int i=0;i<n;i++){
if(vis[i]==0) {
flag=1;
break;
}
}
if(flag) cout<<"NO"<<endl;
else {
cout<<"YES"<<endl;
for(int i=0;i<n;i++){
if(vis[i]==1) cout<<"1"<<" ";
else cout<<"0"<<" ";
}
}
}
397



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



