zoukankan      html  css  js  c++  java
  • HDU6682 Rikka with Mista

    题意

    给出n(<=40)个数,每个数范围1到44444444,选出一些数求和,求(2^n)种选数方案中所求的和含有多少个4。
    题目链接

    思路

    根据数据范围可以判断是折半搜索,两次搜索得出前一半与后一半能够得出的数,分别储存在a,b两个数组,合并时按位枚举每一位有多少个4。如果我们计算第i位,则按照(x%10^{i+1})将a,b排序。对于a[i],第一种情况(4*10^{i})<=a[i]+b[i]<(5*10^{i})是一段区间,第二种情况(14*10^{i})<=a[i]+b[i]<(15*10^{i})也是一段区间。我们用滑动窗口对两种情况分别计数。每次排序要用基数排序,不然可能会T。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn = 3000000+10;
    
    struct node
    {
        LL x,y;
        int c;
    };
    
    int n,na,nb;
    node a[maxn],b[maxn],tmp[maxn];
    LL p[25];
    int X[maxn],cnt[25];
    LL ans;
    
    void dfs(int x,int N,LL sum,bool tag)
    {
        if (x==N+1)
        {
            if (!tag) a[++na].x=sum; else b[++nb].x=sum;
            return;
        }
        dfs(x+1,N,sum,tag);
        dfs(x+1,N,sum+(LL)X[x],tag);
    }
    
    int main()
    {
        p[0]=1;
        for (int i=1;i<=11;i++) p[i]=p[i-1]*10LL;
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            for (int i=1;i<=n;i++) scanf("%d",&X[i]);
            int mid=(n+1)>>1;
            na=nb=0;
            ans=0;
            dfs(1,mid,0,0);
            dfs(mid+1,n,0,1);
            for (int i=1;i<=na;i++) a[i].y=0;
            for (int i=1;i<=nb;i++) b[i].y=0;
            for (int o=0;o<=9;o++)
            {
                for (int i=0;i<=9;i++) cnt[i]=0;
                for (int i=1;i<=na;i++) a[i].c=(a[i].x/p[o])%10,cnt[a[i].c]++;
                for (int i=1;i<=9;i++) cnt[i]=cnt[i-1]+cnt[i];
                for (int i=na;i>=1;i--) tmp[cnt[a[i].c]--]=a[i];
                for (int i=1;i<=na;i++) a[i]=tmp[i],a[i].y+=p[o]*(LL)a[i].c;
    
                for (int i=0;i<=9;i++) cnt[i]=0;
                for (int i=1;i<=nb;i++) b[i].c=(b[i].x/p[o])%10,cnt[b[i].c]++;
                for (int i=1;i<=9;i++) cnt[i]=cnt[i-1]+cnt[i];
                for (int i=nb;i>=1;i--) tmp[cnt[b[i].c]--]=b[i];
                for (int i=1;i<=nb;i++) b[i]=tmp[i],b[i].y+=p[o]*(LL)b[i].c;
    
                int l=0,r=0;
                LL L,R;
                L=p[o]*4LL; R=p[o]*5LL;
                for (int i=na;i>=1;i--)
                {
                    while (r+1<=nb&&b[r+1].y+a[i].y<R) r++;
                    while (l+1<=r&&b[l+1].y+a[i].y<L) l++;
                    ans+=(LL)(r-l);
                }
                L=p[o]*14LL; R=p[o]*15LL;
                for (int i=na;i>=1;i--)
                {
                    while (r+1<=nb&&b[r+1].y+a[i].y<R) r++;
                    while (l+1<=r&&b[l+1].y+a[i].y<L) l++;
                    ans+=(LL)(r-l);
                }
    
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/zhanggengchen/p/11406422.html
Copyright © 2011-2022 走看看