51nod 1557 两个集合

来源:互联网 发布:知乎成都工作 编辑:程序博客网 时间:2024/06/05 02:01

先是用快排+二分,判断各种情况,后来发现会漏掉某些情况,然后看数据,感觉可以用二分图匹配来做,但是有自环的情况,我不会处理,不过评论里面有人用二分图匹配做,也是位大佬这里写图片描述
然后就看了大佬的讲解,也是快排+二分,但是情况判断的很准

我用的方法复杂度是 O(nlogn),快排+二分,思路挺简单,但是容易漏,要想全才行。这个问题也就是数对儿问题,x+pA=a 或者 x+pB=b。

首先,我们只用分析 NO 的情况,其他的都是 YES,NO 的情况有两种:
One:x 既不在 A 中,也不在 B 中,即找不到 a-x 和 b-x,NO;
Two:x 既可以在 A 中,也可以在 B 中,也就是找到了 a-x 和 b-x,如果 x 在 A 中,那么 b-x 一定不在 B 中,因为数唯一,所以 b-x 只能在 A 中,也就是说必须存在 a-(b-x),如果不存在就行不通,同理得如果 x 在 B 中,则必须存在 b-(a-x),如果不存在就行不通,那么如果两个方案都行不通了,也就是说 NO 了。

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5+10;int n,a,b;int num[MAXN];bool mark[MAXN];int BS(int number){    int l = 0;    int r = n-1;    int mid;    while(l <= r)    {        mid = (l+r) >> 1;        if(num[mid] < number)            l = mid + 1;        else if(num[mid] > number)            r = mid - 1;        else            return mid;    }    return -1;}int main(){    int aindex,bindex,acur,bcur;    ios::sync_with_stdio(false);    cin >> n >> a >> b;    for(int i = 0; i < n; ++i)        cin >> num[i];    sort(num,num+n);    int flag;    for(int i = 0; i < n; ++i)    {        acur = a - num[i];        bcur = b - num[i];        aindex = BS(acur);        bindex = BS(bcur);        if(aindex == -1 && bindex == -1)        {            cout << "NO" << endl;            return 0;        }        if(aindex !=-1 && bindex != -1)        {            aindex = BS(a-(b-num[i]));            bindex = BS(b-(a-num[i]));            if(aindex == -1 && bindex == -1)            {                cout << "NO" << endl;                return 0;            }        }    }    cout << "YES" << endl;    return 0;}
原创粉丝点击