51nod 1557(两个集合)

来源:互联网 发布:刘怀 大数据 编辑:程序博客网 时间:2024/06/14 22:01

题目:
小X有n个互不相同的整数: p1,p2,…,pn 。他想把这些整数分到两个集合A和B里边。但是要符合下面两个条件。
· 如果x属于A,那么a-x也肯定属于A。
· 如果x属于B,那么b-x也肯定属于B。
判断一下是否存在一种方案来分配这些数字到集合A,B中。
注意:如果一个集合为空也是可以的。(数据结构,Hash,并查集,CodeForces)

其实不是很懂这个题跟并查集的联系,看到有这个标签分类,就边查资料边做了一下。

只要判断(a-x)或者(b-x)在集合中,如果两个都在的话,就进一步判断(a-(b-x))或者(b-(a-x))是否在集合中即可。

解决代码:

#include <iostream>#include <algorithm>#define maxl 10000000using namespace std;int n,a,b;int ns[maxl]={0};bool sear(int number)//用二分法进行查找 {    int l = 0,r = n-1,mid;    while(l <= r)    {        mid = (r+l)/2;        if(ns[mid] > number)        r = mid-1;        else if(ns[mid] < number)        l = mid+1;        else        return true;    }       return false;} int main(){    while(~scanf("%d%d%d",&n,&a,&b))    {        for(int i = 0;i < n;i++)        {            scanf("%d",&ns[i]);        }        sort(ns,ns+n);//sort函数对数组进行升序排列,方便二分法查找         for(int i = 0;i <= n;i++)        {            bool n1 = sear(a-ns[i]);            bool n2 = sear(b-ns[i]);            if(!n1 && !n2)//在两个集合中的任何一个都可以             {                printf("NO!\n");                return 0;            }            if(n1 && n2)//两个集合都满足,则进行深层考虑             {                bool n3 = sear(b-(a-ns[i]));                bool n4 = sear(a-(b-ns[i]));                if(!n3 && !n4)                {                    printf("NO!\n");                    return 0;                }             }         }        printf("YES!\n");        return 0;    }}

补充一个用到的知识点:

sort函数:包含于头文件中,这个函数可以传两个参数或三个参数。第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一地址。也就是说,排序的区间是 [a,b) 。简单来说,有一个数组 int a[100] ,要对从 a[0] 到 a[99] 的元素进行排序,只要写 sort(a,a+100) 就行了,默认的排序方式是升序。

原创粉丝点击