Codeforces 949E Binary Cards

Posted yuzao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 949E Binary Cards相关的知识,希望对你有一定的参考价值。

Description

给出一个长度为 (n) 的数组,求使得用最少数量的 (2^k)(-2^k) 的数,使得数组中的每一个元素都可以被你选出的 (2) 的次幂表示
题面

Solution

注意到两个性质:
1.一个数不会用两次,举个例子:用两个 (2),不如用 (2,4) 范围广
2.一个数不会既用 (2^k) 又用 (-2^k),显然用 (-2^k,2^{k+1}) 或者 (2^k,-2^{k+1}) 更优

这样就可以依次考虑每一位了:
如果所有的数都不含有这一位,那么就直接把所有的数除以 (2)
如果存在数含有这一位,那么用 (-2^k) 或者 (2^k) 把含有这一位的数都给去掉,然后再把所有的数除以 (2)
对于第二种情况我们直接搜索一下就好了

这样复杂度有些问题,但是我们把数去重之后,第 (k) 层的数就最多只有 (frac{max(A[i])}{2^{k}})
复杂度就变成了分治的复杂度了

#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N],b[21][N],top=0,st[N],ans[N],anslen=N;
inline void dfs(int t,int n){
    if(t>20 || top>=anslen)return ;
    if(n==1 && !b[t][1]){
        if(top<anslen){
            anslen=top;
            for(int i=1;i<=top;i++)ans[i]=st[i];
        }
        return ;
    }
    bool flag=1;
    for(int i=1;i<=n;i++)if(b[t][i]&1){flag=0;break;}
    if(flag){
        for(int i=1;i<=n;i++)b[t+1][i]=b[t][i]>>1;
        n=unique(b[t+1]+1,b[t+1]+n+1)-b[t+1]-1;
        dfs(t+1,n);
        return ;
    }
    for(int w=-1;w<=1;w+=2){
        for(int i=1;i<=n;i++)
            if(b[t][i]&1)b[t+1][i]=(b[t][i]+w)>>1;
            else b[t+1][i]=b[t][i]>>1;
        st[++top]=-w*(1<<t);
        int tmp=unique(b[t+1]+1,b[t+1]+n+1)-b[t+1]-1;
        dfs(t+1,tmp);
        top--;
    }
}
int main()
{
    freopen("pp.in","r",stdin);
    freopen("pp.out","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    n=unique(a+1,a+n+1)-a-1;
    for(int i=1;i<=n;i++)b[0][i]=a[i];
    dfs(0,n);
    printf("%d
",anslen);
    for(int i=1;i<=anslen;i++)printf("%d ",ans[i]);
    return 0;
}

以上是关于Codeforces 949E Binary Cards的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 1003B Binary String Constructing

[CodeForces - 1225C]p-binary 数论二进制

Codeforces 1360H - Binary Median (二分)

Codeforces 1360H - Binary Median (二分)

CodeForces E. Binary Numbers AND Sum

CodeForces - 1225C p-binary(思维)