zoukankan      html  css  js  c++  java
  • C. Beautiful Numbers

    C. Beautiful Numbers

    Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 524288/262144K (Java/Other)
    Total Submission(s) : 27   Accepted Submission(s) : 7
    Problem Description

    Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the decimal representation of this integer only contains digits a and b. Vitaly calls a good number excellent, if the sum of its digits is a good number.

    For example, let's say that Vitaly's favourite digits are 1 and 3, then number 12 isn't good and numbers 13 or 311 are. Also, number 111 is excellent and number 11 isn't.

    Now Vitaly is wondering, how many excellent numbers of length exactly n are there. As this number can be rather large, he asks you to count the remainder after dividing it by 1000000007 (109+7).

    A number's length is the number of digits in its decimal representation without leading zeroes.

     
    Input

    The first line contains three integers: abn (1≤a<b≤9,1≤n≤106).

     
    Output

    Print a single integer the answer to the problem modulo 1000000007 (109+7).

     
    Sample Input
    1 3 3
    2 3 10
     
    Sample Output
    1
    165
     /*
    题目:Beautiful number
    题意:给两个数a,b;如果某个数的每一位上都是由a或b组成如:a = 1 ,b=3; 则n=113那么n就是good number;
    如果某个数满足是good number;且各个位上的数的和,也是good number;那么这个数称为excellent number;
    求n长度的位数的数,有多少个满足a,b的excellent number; 结果%(10^9+7);
    思路:排列组合的方法; 首先n个长度的数s,必须是若干个a,b组成的每一位上; 所以设有x个a, y个b,那么x*a+y*b==s; x+y==n;
    所以枚举处所有的x,y = n-x; 所以也可以求出s=a*x+y*b;然后判断s是否每一位上都是a或者b;如果是的话,那么排列组合x在n中的组合方法数;
    */
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<cctype>
    #include<set>
    #include<map>
    typedef __int64 ll;
     
    using namespace std;
    const int maxn = 1e6+5;
    const int inf = 0x3f3f3f3f;
    const int INF = 0xfffffff;//更小;
    const ll mod = 1e9+7;
    ll fact[maxn];
    ll save[1000], z, a, b, n;
    int bitlen;
    /*刚开始我打算把小于等于b*n的所有符合good number的数字s找出来,然后再判断能否有x个a,y个b使得x*a+y*b==s 且x+y==n;
    然而这种最多达到128;所以:128*n(1*10^6); 会超时;
    void dfs(ll s,ll sum)
    {
        ll t = sum*10;
        if(t+a>s) return ;
        save[z++] = t+a;
        dfs(s,t+a);
        if(t+b>s) return ;
        save[z++] = t+b;
        dfs(s,t+b);
    }*/
    int isgood(int x) {
        for(; x; x/=10) {
            if(x%10 != a && x%10 != b) {
                return 0;
            }
        }
        return 1;
    }
     
    ll ext_gcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0) {
            x = 1, y = 0; return a;
        }
        ll d = ext_gcd(b,a%b,x,y);
        ll t = x; x = y;
        y = t-a/b*y;
        return d;
    }
    ll Pow(ll a,ll b)//92ms
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
            {
                b--;
                ans=(ans*a)%mod;
            }
            else
            {
                b/=2;
                a=(a*a)%mod;
            }
        }
        return ans;
    }
    //92ms;相同;
    ll inv_mod(ll a)  // ix=1(mod n)  这里是求逆元的第二种方法;第一种是快速幂;
    {
        ll x, y, d;
        d = ext_gcd(a, mod, x, y);
        while(x<0) { x+=mod; }
        return x;
    }
    ll Multi(ll x0)
    {
        return ((fact[n]%mod)*Pow(fact[x0]*fact[n-x0]%mod,mod-2))%mod;//快速幂的方法;
      //  return ((fact[n]%mod)*inv_mod(fact[x0]*fact[n-x0]%mod)%mod+mod)%mod;//这里是(a/b)%mod==(a%mod)*(inver(b)%mod)%mod;
                                                                            //同时发现,(a1*a2*...*an)^(M-2)%mod;等价于:先对里面的结果取余,再对它的次方计算取余;
    }
     
    int main()
    {
        ll x, y, gcd, x0, y0, ans;
        fact[0] = 1;
        for(ll i = 1; i <= 1000000; i++){//初始化阶乘值;
            fact[i] = fact[i-1]*i%mod;
        }
        while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
        {
            ll s = n*b;
            z = ans = 0;
            gcd = ext_gcd(a,b,x,y);
        //    dfs(s,0);//获得good number;
       //     for(int i = 0; i < z; i++){
                for(ll i = 0; i <= n; i++){///这样确实快了不少;复杂度约为7*n(7*10^6);
                    if(isgood(a*i+b*(n-i))){
                        ans = (ans+Multi(i))%mod;
                    }
                }
       //     }
            /**为什么下面的不行;数据:6 8 14215 答案:651581472 我的是:0;也就是没有达到第131行的那一步;
               如果实在找不到错误的处理方法和原因,姑且换一种方法吧;
            */
    /*
            for(int i = 0; i < z; i++){
                if(save[i]%gcd!=0) continue;
                gcd = ext_gcd(a,b,x,y);
                x0 = save[i]/gcd*x;
                y0 = save[i]/gcd*y;
                ll t = b/gcd;
                while(x0>t) {
                    x0 = x0%t;
                    y0 += x0/t*(a/gcd);
                }
                for(ll k = 0;  ; k++){
                    x0 += k*b/gcd;// x0 个 a;
                    y0 -= k*a/gcd;// y0 个 b;
                    if(y0<0) break;
                    if(x0<0||x0+y0!=n) continue;
                    ans += ((fact[n]%mod)*inv_mod(fact[x0]*fact[n-x0]%mod)%mod+mod)%mod;
                    ans %= mod;
                }
            }*/
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    战略就是做出各种选择和不断权衡取舍;战略就是要刻意与众不同
    获取基目录,它由程序集冲突解决程序用来探测程序集
    Entity Framework的原理及使用方式
    NHibernate使用之详细图解
    最重要的不是你认识多少个人,而是你认识多少种人
    强关系利于执行,弱关系利于创新
    判断它是不是你的社群成员,你要看它对你的态度
    粉丝不在于多,在于够残
    没有请不起的人才,只有付不起的诚意
    所有有可能被互联网取代的组织一定会被取代--颠覆式创新研习社
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/4844876.html
Copyright © 2011-2022 走看看