• CF468B Two Sets


    CF468B Two Sets

    洛谷传送门

    题意翻译

    给出 nn 个各不相同的数字,将它们分别放入 AA 和 BB 两个集合中,使它们满足:

    • 若数字 xx 在集合 AA 中,那么数字 a-xax 也在集合 AA 中;
    • 若数字 xx 在集合 BB 中,那么数字 b-xbx 也在集合 BB 中。 输入格式:

    输入的第一行输入三个整数 n,a,b (1 leq n leq 10^{5} ; 1 leq a,b leq 10^{9} )n,a,b(1≤n≤105;1≤a,b≤109)。

    输入的第二行有 nn 个各不相同的正整数,且每个正整数的数值大小都在 [1,10^{9}][1,109] 内。 输出格式:

    若不能能将这 nn 个数在满足条件的情况下全部放入 AA 和 BB 这两个集合中,则输出 NO

    若这 nn 个数在满足条件的情况下能被全部放入 AA 和 BB 这两个集合中,则第一行输出 YES ,第二行输出 nn 个数 00 或 11 ,第 ii 个数为 00 表示第 ii 个数在集合 AA 中,第 ii 个数为 11 表示第 ii 个数在集合 BB 中。


    题解:

    很容易看出来这道题最难搞的是冲突的处理,也就是a-x,b-x和x同时存在于原数列的情况。

    于是就有了思路(比较清奇,因为是先想到什么东西难搞,然后再回推思路)

    也就是:

    对于一个(x)来说,能分成以下4种情况进行分类讨论:

    1.(a-x)不存在,(b-x)不存在。这种情况直接NO。

    2.(a-x)存在,(b-x)不存在。这种情况是集合A。

    3.(a-x)不存在,(b-x)存在。这种情况是集合B。

    4.(a-x)存在,(b-x)存在。

    第四种情况就是着重要讨论的冲突情况。

    那么我们接下就需要再找到一个证据来唯一确定这个数的从属集合。也就是:还需要判断是否存在(y)(a-y=b-x)或者(b-y=a-x)其中之一存在。

    如果存在(a-y=b-x),那么就把(x)(a-x)(y)(a-y(b-x))都放到集合A中。同理(b-y=a-x)存在的情况。如果都不存在就输出NO。

    然后我们采用并查集来维护这个东西。

    我还写了个版本是(set)直接模拟维护的,但是挂了,,,有兴趣的同学请去讨论区康康,感谢抓虫。

    代码:

    #include<cstdio>
    #include<map>
    #include<algorithm>
    using namespace std;
    const int maxn=1e5+5;
    int maxx,n,a,b,fa[maxn],val[maxn];
    map<int,int> mp;
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void merge(int x,int y)
    {
    	int fx=find(x),fy=find(y);
    	if(fx!=fy)
    		fa[fx]=fy;
    }
    int main()
    {
    	scanf("%d%d%d",&n,&a,&b);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&val[i]);
    		mp[val[i]]=i;
    		maxx=max(maxx,val[i]);
    		fa[i]=i;
    	}
    	fa[0]=0;
    	fa[n+1]=n+1;
    	if(maxx>=max(a,b))
    	{
    		printf("NO");
    		return 0;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		if(mp[a-val[i]]>0) 
    			merge(i,mp[a-val[i]]);
    		else 
    			merge(i,n+1);
    		if(mp[b-val[i]]>0) 
    			merge(i,mp[b-val[i]]);
    		else 
    			merge(i,0);
    	}
    	int l=find(0),r=find(n+1);
    	if(l!=r)
    	{
    		puts("YES");
    		for(int i=1;i<=n;i++)
    		{
    			if(i!=1) 
    				printf(" ");
    			if(find(i)==l) 
    				printf("0");
    			else 
    				printf("1");
    		}
    	}
    	else 
    		puts("NO");
    	return 0;
    }
    
  • 相关阅读:
    mysql数据库基本操作sql语言
    asp.net MVC4 表单
    asp.net MVC4 表单
    Mysql字符集设置
    zen Code 支持的代码样式
    sqlserver数据库标注为可疑的解决办法(转)
    SQL Server遍历表的几种方法
    GridView 动态添加绑定列和模板列
    TransactionScope 之分布式配置
    sql server 执行上100mb sql sql sql server 无法执行脚本 没有足够的内存继续执行
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14018232.html
Copyright © 2020-2023  润新知