先是用快排+二分,判断各种情况,后来发现会漏掉某些情况,然后看数据,感觉可以用二分图匹配来做,但是有自环的情况,我不会处理,不过评论里面有人用二分图匹配做,也是位大佬
然后就看了大佬的讲解,也是快排+二分,但是情况判断的很准
“
我用的方法复杂度是 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;
}