码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 949E Binary Cards

时间:2018-07-14 22:18:09      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:例子   flag   class   stdin   个数   n+1   rds   scanf   cpp   

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\n",anslen);
    for(int i=1;i<=anslen;i++)printf("%d ",ans[i]);
    return 0;
}

Codeforces 949E Binary Cards

标签:例子   flag   class   stdin   个数   n+1   rds   scanf   cpp   

原文地址:https://www.cnblogs.com/Yuzao/p/8620208.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!