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

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

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

  • 相关阅读:
    PowerDesigner快捷键
    Android 的开源电话/通讯/IM聊天项目全集
    Android ContentProvider完整案例
    Android中观察者模式的升入理解
    Android中Socket大文件断点上传
    Storm概念学习系列之Tuple元组(数据载体)
    开始使用storm
    Storm概念学习系列之storm的功能和三大应用
    Storm概念学习系列之storm的特性
    Storm概念学习系列之storm核心组件
  • 原文地址:https://www.cnblogs.com/BaseAI/p/13960215.html
Copyright © 2011-2022 走看看