设为首页 加入收藏

TOP

最后一个非零数字(POJ 1604、POJ 1150、POJ 3406)(八)
2019-06-11 12:08:21 】 浏览:346
Tags:最后 一个 数字 POJ 1604 1150 3406
8,10}。可以对两个子序列分别进行统计。

       子序列1由小于等于n的奇数组成,设函数getOdd(n,x)表示小于等于n的奇数中末位数字为奇数x的数的个数。而子序列2中的每个数除以2后,得到一个从1~n/2的子序列。例如,{2,4,6,8,10}中的每个数除以2,就是序列{1,2,3,4,5},也就是说这个问题可看成一个原来问题的子问题。

       由此,可得到递推式getLast(n,x) = getLast(n/2,x) +getOdd(n,x)。

      getOdd(n,x)怎么求呢?观察小于等于n的奇数序列(有n/2个数)。按末位数字分成5组{1,11,21,31,…},{3,13,23,33,…},{5,15,25,35,…},{7,17,27,37,…},{9,19,29,39,…},每组至少有n/10个数。由于n不一定是10的倍数,还需看看n%10>=x是否成立,成立就加1,不成立就不加1。在这5组中,末位数字为5的组中每个数都含有质因子5,要去掉5这个因子,每个数除以5后,序列又变成了{1,3,5,7,…},该序列中n/10个数奇数,所有的奇数小于等于n/5,也就是说这个问题也看看成一个原来问题的子问题。

       由此,可得到递推式 getOdd(n,x)=n/10+(n%10>=x)+getOdd(n/5,x)。

      有了上面这两个递推式,采用递归的方法能很快求得1~n序列中末位数字为3、7、9的数的个数。

      (5)可Accepted的源程序3。

#include <iostream>  

using namespace std; 

int getFactor(int n,int k)  

    int cnt=0; 

    while(n) 

    { 

        cnt+=n/k; 

        n/=k; 

    } 

    return cnt; 

int getOdd(int n,int k) 

    if (n==0) return 0; 

    return n/10+(n%10>=k)+getOdd(n/5,k);  

int getLast(int n,int k) 

    if (n==0) return 0; 

    return getLast(n/2,k)+getOdd(n,k); 

int main() 

       int n,m,cnt2,cnt5,cnt3,cnt7,cnt9;

    int last[4][4] ={{6,2,4,8},{1,3,9,7},{1,7,9,3},{1,9,1,9}};  

       while (cin>>n>>m)

       {

             if (m == 0)

              {

                     cout<<"1"<<endl;

                     continue;

              }

        cnt2 = getFactor(n,2) - getFactor(n-m,2); 

        cnt5 = getFactor(n,5) - getFactor(n-m,5); 

        cnt3 = getLast(n,3) - getLast(n-m,3); 

        cnt7 = getLast(n,7) - getLast(n-m,7); 

        cnt9 = getLast(n,9) - getLast(n-m,9); 

        if (cnt2>=cnt5)

              {

                  cnt2=cnt2-cnt5;

               &n

首页 上一页 5 6 7 8 9 下一页 尾页 8/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Example: Getting WMI Data from .. 下一篇POJ中和质数相关的三个例题(POJ ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目