首页 > 学院 > 开发设计 > 正文

51nod 1557 两个集合 【记忆化枚举--判断】

2019-11-06 08:18:28
字体:
来源:转载
供稿:网友

1557 两个集合题目来源: CodeForces基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

小X有n个互不相同的整数: p1,p2,...,pn 。他想把这些整数分到两个集合A和B里边。但是要符合下面两个条件。

·        如果x属于A,那么a-x也肯定属于A。

·        如果x属于B,那么b-x也肯定属于B。

判断一下是否存在一种方案来分配这些数字到集合A,B中。

注意:如果一个集合为空也是可以的。

Input
单组测试数据。第一行有三个整数n,a,b (1≤n≤10^5; 1≤a,b≤10^9)。第二行有n个不一样的整数 p1,p2,...,pn (1≤pi≤10^9).Output
如果可行,那么输出YES,否则输出NO。Input示例
样例输入14 5 92 3 4 5Output示例
样例输出1YES

此题的思路与 hiho一下 第一百三十四周 #1468 : 2-SAT·hihoCoder新春晚会 【2-SAT 之 枚举--搜索】 类似

都是从头开始枚举这个点的两个情况---然后收到这个枚举影响的点加入队列继续枚举----看情况是否成立。

可以先预处理出来每个数的A连点和B连点。

当考虑 i 为A时 ,判断 i 和 i的A连点是否可以为A  --可以的话将 i和i的A连点 放入队列并标记---  

当从队列中取时 , 判断 i 是否有 B连点, 当有B连点j的话,因为 i 已进入A ,那么 j 就不能进入B --- 即只能进入A  --------  (如果有矛盾的情况,则枚举失败,所有此次枚举标记的点恢复未标记状态。) 

考虑 i 为 B 的方法与上面一致-.-      ------------- 飘过-.- 

代码:

#include<stdio.h>#include<string.h>#include<queue>#include<stack>#include<iostream>#include<algorithm>using namespace std;int n,a[100100],b[100100][2],ans[100100];queue<int > qa;stack<int > sa;void my_clear(){    while (!qa.empty())        qa.pop();}void myjinA(int x){    qa.push(x);    sa.push(x);}int main(){    int t,A,B,k,x,y;    cin>>n>>A>>B;    for (int i=0;i<n;i++)        cin>>a[i];    sort(a,a+n);    memset(b,-1,sizeof(b));    memset(ans,-1,sizeof(ans));    bool fafe=true;    for (int i=0;i<n;i++)    {        k=lower_bound(a,a+n,A-a[i])-a;        if (k>=0&&k<n&&a[k]==A-a[i])            b[i][0]=k;        k=lower_bound(a,a+n,B-a[i])-a;        if (k>=0&&k<n&&a[k]==B-a[i])            b[i][1]=k;        if (b[i][0]==b[i][1]&&b[i][0]==-1)            fafe=false;    }    if (!fafe)    {        PRintf("NO/n");        return 0;    }    for (int i=0;i<n;i++)    {        if (ans[i]==-1)        {            //---------入A            if (b[i][0]!=-1&&ans[i]==-1&&ans[b[i][0]]==-1)            {                my_clear();                x=i;y=b[x][0];                myjinA(x);                myjinA(y);                ans[x]=0;                ans[y]=0;                while (!qa.empty())                {                    x=qa.front();                    qa.pop();                    if (b[x][1]!=-1&&ans[b[x][1]]==-1)                    {                        x=b[x][1];                        if (b[x][0]!=-1&&ans[b[x][0]]==-1)                        {                            y=b[x][0];                            myjinA(x);                            myjinA(y);                            ans[x]=0;                            ans[y]=0;                        }                        else                        {                            fafe=false;                        }                    }                    if (!fafe) break;                }                if (!fafe)                {                    while (!sa.empty())                    {                        x=sa.top();                        sa.pop();                        ans[x]=-1;                    }                }            }            //入B            if (b[i][1]!=-1&&ans[i]==-1&&ans[b[i][1]]==-1)            {                fafe=true;                my_clear();                x=i;y=b[x][1];                myjinA(x);                myjinA(y);                ans[x]=1;                ans[y]=1;                while (!qa.empty())                {                    x=qa.front();                    qa.pop();                    if (b[x][0]!=-1&&ans[b[x][0]]==-1)                    {                        x=b[x][0];                        if (b[x][1]!=-1&&ans[b[x][1]]==-1)                        {                            y=b[x][1];                            myjinA(x);                            myjinA(y);                            ans[x]=1;                            ans[y]=1;                        }                        else                        {                            fafe=false;                        }                    }                    if (!fafe) break;                }                if (!fafe)                {                    while (!sa.empty())                    {                        x=sa.top();                        sa.pop();                        ans[x]=-1;                    }                }            }            if (!fafe) break;        }        if (ans[i]==-1)        {            fafe=false;break;        }    }    if (fafe)        printf("YES/n");    else        printf("NO/n");    return 0;}/*3 11 124 7 83 5 62 3 4*/


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表