【数论】Non-Decreasing Digit

该问题要求编写程序,计算具有指定位数的非递减数字的数量。非递减数字是指其所有左侧位数小于等于右侧位数的数字。例如,1234是一个四数字的非递减数字。对于每个数据集,输入包含一个数据集编号和位数N(1≤N≤1000000000),输出为满足条件的N位数字数量对1000000007取模的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

A number is said to be made up of non-decreasing digits if all the digits to the left of any digit is less
than or equal to that digit. For example, the four-digit number 1234 is composed of digits that are
non-decreasing. Some other four-digit numbers that are composed of non-decreasing digits are
0011, 1111, 1112, 1122, 2223. As it turns out, there are exactly 715 four-digit numbers composed of
non-decreasing digits.
Notice that leading zeroes are required: 0000, 0001, 0002 are all valid four-digit numbers with nondecreasing digits.
For this problem, you will write a program that determines how many such numbers there are with a
specified number of digits.

Input

The first line of input contains a single integer P, (1<=P <= 1000), which is the number of data sets that
follow. Each data set is a single line that contains the data set number, followed by a space, followed
by a decimal integer giving the number of digits N, (1<= N <= 1000000000).

Output

For each data set there is one line of output. It contains the data set number followed by a single
space, followed by the number of N digit values that are composed entirely of non-decreasing digits % 1000000007.

Sample Input

31 22 33 4

Sample Output

1 552 2203 715

HINT

Source

代码:

#include<cstdio>
using namespace std;
int main()
{
    int i,n;
    long long ti=1,num;
    scanf("%d",&n);
    for(;n--;ti=1)
    {
              scanf("%d%lld",&i,&num);
              for(int j=1;j<=9;++j)
              {
                    long long temp=num+j;        
                    ti=((ti%1000000007)*(temp%1000000007))%1000000007; 
              }
              ti=(ti*831947206)%1000000007;
              printf("%d %lld\n",i,ti);
    }
    return 0;
}


   

                

其中有个关于模运算除法的技巧:

参考了http://mingplusplus.com/blog/?p=43

Assume:

a%b=0

And we want to know:

(a/b)%m   (m=1000000007)

It could be easy. However, sometimes:

a=a1*a2  (a1>2^63 and a2>2^63)

Then We typically want to use   

(a1%m * a2%m)/(b%m)

That’s where the problem is:  

(a/b)%m != (a%m)/(b%m)

So we want to make a form like: 

(a*c)%m = (a/b)%m

So that we can simply calculate the answer using:

(a1%m*a2%m*c%m)

If

(c*b)%m==1

Then:

(a/b)%m = (a/b)%m * (c*b)%m

(a/b)%m = (a*c)%m

Then we can calculate it.

Summary, to calculate like this form:

(a/b)%m (m is prime)

We have to find a number “c” so that:

(b*c)%m=1

To make

(a*c)%m=(a/b)%m.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值