51nod 1557(两个集合)

题目:
小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 10000000
using 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) 就行了,默认的排序方式是升序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值