【思维+大数(高精度)】number 计蒜客 - 45276

题目:

求 1 到 10^n 的数字中有 3 的数字的数量。

输入格式

1 个整数 n

输出格式

共一行,1 个整数,表示答案。

数据范围

对于 10% 的数据,n8

对于 30% 的数据,n18

对于 100% 的数据,n1000

Sample Input

2

Sample Output

19

题解:

当n=1000时,1e1000内有部分是3e999,这里有1e999个含有数字3的数字,所以很明显该题是大数运算或者是规律题。

进行简单的模拟,

n=1,有ans=1;即10之内只有3;

n=2,有ans=19;即100之内有03,13,23...93,10个与30,31...39,10个,同时因为33是两类的交集,所以要去掉重复的一个;

n=3,有ans=271;1000之内有10个x00~x99, 同时有300~399,(x表示任意数字),即有10个ans2和100,再去除重复的3xx里面的19个重复

所以ans3=ans2*10+100-ans2

n=4,有ans=3439;同理可得ans4=ans3*9+1e(n-1);

所以可归纳出ansn=ans(n-1)*9+1e(n-1);(n>=2)

       ans1=1;

根据该公式可判断出输出并未又整齐固定的规律,所以该题是大数运算。

根据公式可以判断需要用到大数加分和大数乘法。

大数运算其实就是通过数组模拟的数学运算,数组的每一数值表示是一个10进制的位,大数加法就是把每位数字相加并进位,大数乘法就是模拟小学学的那种运算方法,将一个乘数的每一个位乘另一个乘数,并求和。

AC代码:

#include<iostream>
#include<cstring>
#define max(a,b){(((a)>(b))?(a):(b))}
#define claer(x){memset(x,0,sizeof(x));}
using namespace std;

int ans[1005];
int tmp1[1005];int _9[5];
int _10[1005];

int add(int *a, int alen, int *b, int blen) {
    int len = max(alen, blen);
    for (int i = 0; i < len; i++) {
        a[i] += b[i];
        a[i + 1] += a[i] / 10;
        a[i] %= 10;
    }
    len++;
    while (a[len]==0)len--;
    return len+1;
}

int mul(int *a, int alen, int *b, int blen) {
    claer(tmp1);
    int t2len = 0;
    for (int i = 0; i < blen; i++) {
        for (int j = 0; j < alen; j++) {
            tmp1[i + j] += b[i] * a[j];
            tmp1[i + j + 1] += tmp1[i + j] / 10;
            tmp1[i + j] %= 10;
        }
        
    }
    int n = alen + blen+5;
    while (tmp1[n]==0)n--;
    for (int i = 0; i <= n; i++)
        a[i] = tmp1[i];
    return n+1;
}


int main() {
#if 0
    //freopen("number.in", "r", stdin);
    //freopen("number.out", "w", stdout);
#endif
    int n, len = 1;
    cin >> n;
    ans[0] = 1;
    _9[0] = 9;
    for (int i = 1; i < n; i++) {
        len = mul(ans, len, _9, 1);

        _10[i] = 1;
        _10[i - 1] = 0;

        len = add(ans, len, _10, i + 1);
    }

    for (int i = len - 1; i >= 0; i--) {
        printf("%d", ans[i]);
    }


}

 


 

posted @ 2020-05-22 11:15  _comet  阅读(159)  评论(0编辑  收藏  举报