zoukankan      html  css  js  c++  java
  • [ AtCoder Grand Contest 031] C

    Problem

    题目地址

    Solution

    前置

    题解

    • 结论1:有解必要条件(A)(B) 在二进制下不同的位数是奇数。

    • 结论2:(A)(B) 在二进制下不同的位数是奇数,那么就可以构造出一组解。换言之,(A)(B) 在二进制下不同的位数是奇数,是有解充分条件

    考虑用分治法构造一组解。设原问题为 (f(A,B,s))(s) 是一个(01)序列,表示二进制下可以调整的位,其中(0)表示不可调整,(1)表示可以调整,原问题的 (s) 是一个长度为 (n) 的全为 (1) 的序列。

    假设 (A,B)(x) 位是不同的,那么固定第 (x),使得构造的解左半部分第 (x) 位全和 (A) 相同,右半部分第 (x) 位全和 (B) 相同,此时 (s') 将在原 (s) 的基础上将第 (x) 位修改为(0)。将 (A) 剩下可以调整的任意一位修改,令其为 (mid)。则原问题就变成了 (f(A,mid,s'))(f(mid,B,s'))。注意 (mid->B) (也就是右半部分)(mid) 的第 (x) 位也要和 (B) 一样。

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch = getchar();
        while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
        return x * f;
    }
    int n,A,B;
    int Calc(int x) {
    	if(x==0) return 0;
    	int res = 0;
    	while(x) {
    		++res; x -= x&-x;
    	}
    	return res;
    }
    void Dfs(int a,int b,int s) {
    	if(s) {
    		int x = (a^b) & s; x = x & -x;
    		s ^= x;
    		int mid = a ^ (s & -s);
    		Dfs(a,mid,s); Dfs(mid^x,b,s);
    	} else printf("%d ",a);
    }
    int main()
    {
    	n = read(); A = read(); B = read();
    	if(Calc(A^B) & 1) {
    		puts("YES"); Dfs(A,B,(1<<n)-1);
    	} else puts("NO");
        return 0;
    }
    /*
    2 1 3
    
    YES
    1 0 2 3
    */
    

    Summary

    • 根据题目猜想出一些结论。

    • 二进制问题考虑分治思想

  • 相关阅读:
    python 笔记——生成器和迭代器
    Python装饰器
    python 小程序—三级菜单—循环和字典练习
    python 小程序—循环和列表训练
    lvs主备可以自由切换,vip落在主上的时候,端口无法telnet,业务连接不了
    mongodb学习
    lvs DR模式
    去哪儿网mysql语法审核工具Inception正式开源
    无法远程连接ubuntu下的mysql
    值得珍藏的28本股市投资经典著作
  • 原文地址:https://www.cnblogs.com/BaseAI/p/13960215.html
Copyright © 2011-2022 走看看