Вопрос: http://codeforces.com/contest/468/problem/B
Маленький X имеет n различных целых чисел: p1, p2, …, pn. Он хочет разделить их все на два набора A и B. Следующие два условия должны быть выполнены:
Если число x принадлежит множеству A, то число a — x также должно принадлежать множеству A.
Если число x принадлежит множеству B, то число b — x также должно принадлежать множеству B.
Помогите Маленькому Х разделить числа на два набора или определить, что это невозможно.
вход
Первая строка содержит три разделенных пробелом целых числа n, a, b (1 ≤ n ≤ 105; 1 ≤ a, b ≤ 109). Следующая строка содержит n разделенных пробелом различных целых чисел p1, p2, …, pn (1 ≤ pi ≤ 109).
Выход
Если есть способ разделить числа на два набора, выведите «YES» в первой строке. Затем выведите n целых чисел: b1, b2, …, bn (bi равно 0 или 1), описывая деление. Если bi равно 0, то pi принадлежит множеству A, в противном случае оно принадлежит множеству B.
Если это невозможно, выведите «NO» (без кавычек).
Теперь я разработал следующий код:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
int n,a,b,id;
int p[100100];
set<int> st;
map<int,int> mp;
int fa[100100];
int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void Bing(int a,int b)
{
int A=find(a),B=find(b);
if(A==B) return ;
fa[B]=A;
}
int main()
{
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++)
{
scanf("%d",p+i);
st.insert(p[i]);
mp[p[i]]=++id;
fa[i]=i;
}
fa[n+1]=n+1;///A
fa[n+2]=n+2;///B
for(int i=1;i<=n;i++)
{
int x=p[i];
int flag = 0;
if(st.count(a-x))
{
Bing(mp[x],mp[a-x]);
flag = 1;
}
else
{
Bing(n+1,mp[x]);
flag = 1;
}
if(st.count(b-x) && flag == 0)
{
Bing(mp[x],mp[b-x]);
}
else if (flag == 0)
{
Bing(n+2,mp[x]);
}
}
if(find(n+1)==find(n+2))
{
puts("NO");
}
else
{
puts("YES");
for(int i=1;i<=n;i++)
{
printf("%d ",find(i)==find(n+1));
}
putchar(10);
}
return 0;
}
По сути, попробуйте объединить каждый элемент либо в наборе A, либо в наборе B. И, наконец, выведите NO, если оба они объединены по очереди. Тем не менее, это дает неправильный ответ на входе, как:
3 3 4
1 2 4
Выход должен быть: NO
тогда как мой код дает вывод как
YES
0 0 1
Где я ошибаюсь в моей логике? Пожалуйста помоги!
Рассмотрим следующие случаи для P
быть набором всех входных чисел p[i]
:
n1 in P
это удовлетворяет n1 = a - p[i]
но нет номера n2 in P
это удовлетворяет n2 = b - p[i]
n1 in P
это удовлетворяет n1 = b - p[i]
но нет номера n2 in P
это удовлетворяет n2 = a - p[i]
n in P
это удовлетворяет n = a - p[i]
ИЛИ ЖЕ n = b - p[i]
n1 in P
это удовлетворяет n1 = a - p[i]
И номер n2 in P
это удовлетворяет n2 = b - p[i]
Что бы ни случилось, если вы столкнетесь с ситуацией 3. или 4. вы хотите сообщить об ошибке («НЕТ»).
Если все числа p[i]
относятся к случаю 1. или 2. результат должен быть действительным.
Вы должны проверять свой код построчно, если он совместим с приведенными здесь случаями.
Других решений пока нет …