zoukankan      html  css  js  c++  java
  • 前缀和的应用 CodeForces

    题目链接:

    https://vjudge.net/problem/1377985/origin

    题目大意就是要你把一个数字拆开,然后相乘。

    要求得数要小于9,否则递归下去。

    这里用到一个递归函数:

    int f(int x)
    {
        if(x < 10) return x;
        int ans = 1;
        while(x)
        {
            if(x%10 != 0) ans *= x%10;
            else ans *= 1;
            x /= 10;
        }
        return f(ans);
    }

    这个函数用来求得一个数字最终得到的那个k值是多少。

    然后开一个二元数组记录一下,并且用到了前缀和,统计从1开始k值出现的次数:(打表)

    void get_table()
    {
        for(int i = 1; i <= MX; ++i) mp[i][f(i)]++;
        for(int i = 1; i <= MX; ++i)
            for(int j = 1; j <= 9; ++j)
                mp[i][j] += mp[i-1][j];
    }

    最后,得到代码如下:(AC代码)

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    const int MX = 1e6+10;
    int mp[MX][10];
    
    int f(int x) //递归求值
    {
        if(x < 10) return x;
        int ans = 1;
        while(x)
        {
            if(x%10 != 0) ans *= x%10;
            else ans *= 1;
            x /= 10;
        }
        return f(ans);
    }
    
    void get_table() //打表求值
    {
        for(int i = 1; i <= MX; ++i) mp[i][f(i)]++;
        for(int i = 1; i <= MX; ++i)
            for(int j = 1; j <= 9; ++j)
                mp[i][j] += mp[i-1][j];
    }
    
    int main()
    {
        get_table();
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int le, ri, k;
            scanf("%d%d%d", &le, &ri, &k);
            int ans = mp[ri][k] - mp[le-1][k]; //left减一的理由是从le开始包括le, 若不减一的话left也会被减掉!
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    如有疑问,欢迎评论!

    化繁为简 大巧不工
  • 相关阅读:
    Privacy Policy
    MINE
    IOS的浅拷贝和深拷贝
    Mine
    IOS8Preview-xCode_6
    IOS8Preview-Huge for developer and Massive for everyone else
    java-Filter
    Java-servlet
    Java-基本的程序设计结构
    银行应用系统安全性设计(3):密钥及其管理
  • 原文地址:https://www.cnblogs.com/mpeter/p/10290296.html
Copyright © 2011-2022 走看看