zoukankan      html  css  js  c++  java
  • Atcoder Grand Contest 031C(构造,思维,异或,DFS)

    #include<bits/stdc++.h>
    using namespace std;
    int n,a,b,sum;
    void dfs(int x,int y,int ban){
        if(__builtin_popcount(ban^sum)==1){
            printf("%d %d ",y,x^y);
            return;
        }
        for(int i=0;i<n;i++)
            if((~(ban>>i)&1)&&(x>>i&1))
                for(int j=0;j<n;j++)
                    if((~(ban>>j)&1)&&i!=j){
                        dfs(1<<j,y,ban|1<<i);
                        dfs(x^(1<<i)^(1<<j),y^(1<<i)^(1<<j),ban|1<<i);
                        return;
                    }
    }
    /*dfs(x,y,ban)表示需要从状态0走到状态x,ban是一个长度为n的二进制串,其中第i位为1表示这一维已经不存在了,即若这个二进制串总共有p个0,则表示当前需要处理的是在p维空间下从0走到x这件事情。
    划分的时候先找到某个二进制位满足x在这一位上为1(也就是代码里的i),然后在随便选一个在第i位上是0且有奇数个1的数,代码里为了方便我就直接选了某个2^j,然后递归构造0 -> 2^j -> 2^j+2^i -> x的路径就行了。
    那个y是指表明接下来处理的所有数在输出时都要异或上y,这样在划分问题的时候可以比较方便地把子问题归为“从0出发走到x”这种形式。*/
    int main(){
        scanf("%d%d%d",&n,&a,&b);
        sum=(1<<n)-1;
        if(__builtin_popcount(a^b)&1){
            printf("YES ");
            dfs(a^b,a,0);
        }
        else
            printf("NO");
        return 0;
    }
    /*要从0走到AxorB,可以选出一个二进制位p满足AxorB在第p位上值为1,遍历二进制第p位为0的所有点组成的n−1维超立方体后,再去遍历二进制位第p位为1的所有点组成的n−1维超立方体。两个n−1维超立方体之间的连接点的选取是任意的,只需要满足起点终点二进制位不同的位数是奇数。*/

    /*感谢租酥宇大佬的解答*/

    保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
  • 相关阅读:
    Linux下wget下载软件小技巧以及安装jdk、tomcat与ftp服务器
    C++计算二叉树的节点数和高度
    转:POST 400 Bad Request The request sent by the client was syntactically incorrect
    SSM项目spring配置文件详细步骤(分门别类、灵巧记忆)
    IntelliJ IDEA里找不到javax.servlet的jar包
    51nod 1533 && CF538F
    51nod 1189
    51nod 1225
    51nod 1040
    51nod 1610
  • 原文地址:https://www.cnblogs.com/ldudxy/p/10555697.html
Copyright © 2011-2022 走看看