zoukankan      html  css  js  c++  java
  • 【赛后补题】Lucky Probability(CodeForces 110D)

    题意

    给定两个(P,Q)的正整数区间((P,Q)都符合([L,R])这个区间,并且都(le 10^9)),分别从其中随机选出一个数,选出的两个数作为一个新区间的左右端点。要求新区间内的幸运数刚好为(k)个的概率(幸运数指一个数的数位只有4或7)。

    分析

    这题要思考着做。首先能有一个直觉:在(10^9)中间的幸运数肯定不多(2^10左右)。这个可以暴力求出。然后概率如何求?所有的情况一定是((P_r-P_l+1)(Q_r-Q_l+1))这么多,然后符合条件的幸运数区间一共有(l_tot-k+1)个(([Lucky_{i},Lucky_{i+k-1}]))这么多。为了计算所有情况,我们只能遍历所有幸运数区间,看在什么情况下能符合题意(显然不会去遍历(10^9)的P、Q的区间)。对于每个这样的([Lucky_{i},Lucky_{i+k-1}])区间,能够与他们相交的P、Q是存在两种情况的:a)P<Q;b) P>Q。我们分类讨论即可。简单地说,先计算Lucky区间与([P_l,P_r])的交集(相当于在a情况下考虑区间头),然后再计算Lucky区间与([Q_l,Q_r])的交集,将两个结果相乘即是符合第i个幸运区间的可能情况。同样地,还要对反向地(即PQ交换)再计算一遍。注意对(k=1)情况的特判。
    遍历所有的幸运区间后,概率就不难求得了。

    代码(Java)

    /*
     * ACM Code => cf110d.java
     * Written by Sam X
     * Date: 三月, 08, 2019
     * Time: 14:27
     */
    import java.util.*;
    import java.math.*;
    
    public class cf110d
    {
        static ArrayList<Long> vec = new ArrayList<>();
        static void dfs(long x)
        {
            if(x>1e9) return;
            if(x*10+4<1e9)
            {
                vec.add(x*10+4);
                dfs(x*10+4);
            }
            if(x*10+7<1e9)
            {
                vec.add(x*10+7);
                dfs(x*10+7);
            }
        }
        static final long contain(long x1, long y1, long x2, long y2)
        {
            return Math.max(Math.min(y1,y2)-Math.max(x1,x2)+1,0l);
        }
        public static void main(String args[])
        {
            Scanner cin = new Scanner(System.in);
            long pl = cin.nextLong(), 
                 pr = cin.nextLong(), 
                 vl = cin.nextLong(),
                 vr = cin.nextLong(),
                 k = cin.nextLong();
        
            dfs(0);
            vec.add(0l);
            vec.add((long)1e9);
    
            Collections.sort(vec);
            /*
            for(long x: vec)
            {
                System.out.print(x+" ");
            }
            System.out.println();
            */
            long ans=0;
    
            int sz=vec.size()-2;
            for(int i=1; i<=sz-k+1; ++i)
            {
                int j=i+(int)k-1;
                ans+=contain(vec.get(i-1)+1, vec.get(i), pl, pr)*contain(vec.get(j), vec.get(j+1)-1, vl, vr);
                if(vec.get(i)>pr) break;
            }
    
            for(int i=1; i<=sz-k+1; ++i)
            {
                int j=i+(int)k-1;
                ans+=contain(vec.get(i-1)+1, vec.get(i), vl, vr)*contain(vec.get(j), vec.get(j+1)-1, pl, pr);
                if(vec.get(i)>vr) break;
            }
    
            if(k==1)
            {
                for(int i=1; i<=sz; ++i)
                {
                    if(contain(vec.get(i), vec.get(i), pl, pr)!=0 &&
                       contain(vec.get(i), vec.get(i), vl, vr)!=0) ans--;
                }
            }
    
            System.out.printf("%.12f
    ", (double)ans/(vr-vl+1)/(pr-pl+1));
            cin.close();
        }
    }
    
  • 相关阅读:
    隐马尔科夫模型(Hidden Markov Models) 系列之三
    隐马尔科夫模型(Hidden Markov Models) 系列之二
    隐马尔科夫模型(Hidden Markov Models) 系列之一
    详解大端模式和小端模式
    viewController详解
    手机产品设计禁忌
    直接拿来用!最火的iOS开源项目(三)
    直接拿来用!最火的iOS开源项目(二)
    <c:out>标签不能正确输出value中的值
    元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?
  • 原文地址:https://www.cnblogs.com/samhx/p/cf110d.html
Copyright © 2011-2022 走看看