NEFU 二进制枚举与异或运算

异或运算

1、ab值相同 结果为1 不相同结果为0
2、不进位的加法
重要性质:1、同一个值异或两次结果为原数 2、满足交换律
应用:找出现奇数次的字符或数字

#include 

using namespace std;

int main()
{
    int n;
    int k=1;
    while(cin>>n)
    {
        char name[50]= {0},na[50];
        for(int i=0; i<2*n-1; i++)
        {
            scanf("%s",na);
            for(int j=0; j<50; j++)
                name[j]=name[j]^na[j];//交换律
        }
        printf("Scenario #%d\n",k);
        k++;
        printf("%s\n\n",name);
    }
    return 0;
}

二进制运算

与&:0为空集,1为为空集,求交集
或 |:0为空集,1为为空集,求并集
取反~:1变0,0变1

二进制枚举

核心代码(题目特点是n的值较小,例如20左右)
        for(int i=0; i<(1<<n); i++)//数位的移动,能取到范围内所有二进制数
        {
            sum=0;
            for(int j=0; j<n; j++)
            {
                if((i&(1<<j))!=0)//判断数位上是否有数,只有一位1在向左移动
                                //if(i&(1<
                {
                    sum=sum+x[j];//注意本处下标
                }
            }

例如:权力指数

#include 
using namespace std;
int main()
{
    int a;
    while(scanf("%d",&a)!=-1)
    {
        for(int u=0; u<a; u++)
        {
            int n;
            int sumx=0,sum=0;
            scanf("%d",&n);
            int x[25],res[25]= {0};
            for(int i=0; i<n; i++)
            {
                scanf("%d",&x[i]);
                sum=sum+x[i];
            }
            for(int i=0; i<(1<<n); i++)
            {
                sumx=0;
                int mark[25]={0};
                for(int j=0; j<n; j++)
                {
                    if((i&(1<<j))!=0)
                    {
                        sumx=sumx+x[j];
                        mark[j]=1;
                    }
                }
                if(sumx<=(sum/2))
                {
                    for(int k=0; k<n; k++)
                    {
                        if(sumx+x[k]>(sum/2)&&mark[k]==0)
                            res[k]++;
                    }
                }
            }
            for(int i=0; i<n-1; i++)
                printf("%d ",res[i]);
            printf("%d\n",res[n-1]);
        }
    }
    return 0;
}

趣味解题

#include 
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        for(int a=0; a<n; a++)
        {
            int m,jl;
            cin>>m;
            double x[25]= {0},y[25]= {0},z[25]= {0},ac[25]= {0},num=0,p,res=0;
            for(int i=0; i<m; i++)
                cin>>x[i];
            for(int i=0; i<m; i++)
                cin>>y[i];
            for(int i=0; i<m; i++)
                cin>>z[i];
            cin>>jl;
            res=0;
            for(int i=0; i<m; i++)
                ac[i]=1-((1-x[i])*(1-y[i])*(1-z[i]));
            for(int i=0; i<(1<<m); i++)
            {
                num=0,p=1.0;
                for(int j=0; j<m; j++)
                {
                    if(i&(1<<j))
                    {
                        num++;
                        p=p*ac[j];
                    }
                    else
                        p=p*(1-ac[j]);
                }
                if(num==jl)
                    res=res+p;
            }
            printf("%.4lf\n",res);
        }
    }
    return 0;
}

陈老师加油

#include 

using namespace std;

int main()
{
    int t1,res=0;
    scanf("%d",&t1);
    for(int i=0; i<(1<<15); i++)
    {
        int you=0,kou=0,t2;
        t2=t1;
        for(int j=0; j<15; j++)
        {
            if((i&(1<<j))!=0)
            {
                you++;
                t2=t2*2;
            }
            else
            {
                kou++;
                t2=t2-1;
                if(t2==0)
                    break;
            }
        }
        if(t2==0&&you==5&&kou==10)
            res++;
    }
    cout<<res<<endl;
    return 0;
}

此类题均是对模板的运用,明确取数是怎么取,根据题意套模板即可。

你可能感兴趣的:(NEFU)