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: a, b, n (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;
}

C. Beautiful Numbers的更多相关文章

  1. CodeForces 55D Beautiful numbers

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  2. [codeforces 55]D. Beautiful numbers

    [codeforces 55]D. Beautiful numbers 试题描述 Volodya is an odd boy and his taste is strange as well. It ...

  3. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  4. Codeforces Round #181 (Div. 2) C. Beautiful Numbers 排列组合 暴力

    C. Beautiful Numbers 题目连接: http://www.codeforces.com/contest/300/problem/C Description Vitaly is a v ...

  5. Codeforces Beta Round #51 D. Beautiful numbers 数位dp

    D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...

  6. CF 55D - Beautiful numbers(数位DP)

    题意: 如果一个数能被自己各个位的数字整除,那么它就叫 Beautiful numbers.求区间 [a,b] 中 Beautiful numbers 的个数. 分析:先分析出,2~9 的最大的最小公 ...

  7. Codeforces Beta Round #51 D. Beautiful numbers

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  8. Beautiful Numbers(牛客网)

    链接:https://ac.nowcoder.com/acm/problem/17385来源:牛客网 题目描述 NIBGNAUK is an odd boy and his taste is stra ...

  9. CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

    传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...

  10. 【数位dp】Beautiful Numbers @2018acm上海大都会赛J

    目录 Beautiful Numbers PROBLEM 题目描述 输入描述: 输出描述: 输入 输出 MEANING SOLUTION CODE Beautiful Numbers PROBLEM ...

随机推荐

  1. MyEclipse8.0 注册码生成代码

    转自:http://blog.sina.com.cn/s/blog_7ad29e00010199xt.html package com.guaicaicc.register; import java. ...

  2. Android应用经典主界面框架之二:仿网易新闻client、CSDN client (Fragment ViewPager)

    另外一种主界面风格则是以网易新闻.凤凰新闻以及新推出的新浪博客(阅读版)为代表.使用ViewPager+Fragment,即ViewPager里适配器里放的不是一般的View.而是Fragment.所 ...

  3. 加加减减(你真的懂++--吗) C#

    目录  TOC \o "1-3" \h \z \u 自增量. PAGEREF _Toc456268662 \h 1 08D0C9EA79F9BACE118C8200AA004BA9 ...

  4. Deep Learning论文笔记之(三)单层非监督学习网络分析

    Deep Learning论文笔记之(三)单层非监督学习网络分析 zouxy09@qq.com http://blog.csdn.net/zouxy09          自己平时看了一些论文,但老感 ...

  5. 【转】linux性能相关的命令和概念

    1. top命令结果解读 23:31:27:系统时间 up 8 days: 表示从开机到现在,一共运行了8天 1 user:1个用户正在使用系统 load average:系统负载,即任务队列的平均长 ...

  6. GUID转换成16位字符串或19位唯一字符串

    整理几个经常使用GUID转换成16位字符串或19位唯一字符串方法: /// <summary> /// 依据GUID获取16位的唯一字符串 /// Author : 付义方 /// < ...

  7. Drupal的错误和异常处理

    Drupal在配置阶段的最开始就设置了自己的错误处理器和异常处理器: function _drupal_bootstrap_configuration() { set_error_handler('_ ...

  8. DDL语句--改动表

    改动表是指改动数据库中已经存在的表的定义.改动表比又一次定义表简单.不须要又一次载入数据.也不会影响正在进行的服务. MySQL中通过ALTER TABLE语句来改动表.改动表包含改动表名.改动字段数 ...

  9. 【HTML】百度地图webAPI使用

    1.登录百度地图,创建WEB应用,设置白名单.获取该WEB应用的ak 2.在页面引入相应的js和ak 3.效果(CSS不提供): 4.实例化地图map,并给map添加相应的搜索和确定坐标事件 < ...

  10. convertView与ViewHolder有什么区别,好处在哪里

        convertView 在API中的解释是The old view to reuse, if possible, 第一次getView时还没有convertView,这时你便创建了一个新的vi ...