回 帖 发 新 帖 刷新版面

主题:编程计算从1到2008080808之间的整数有多少个含有数字7。

这是金山的笔试题,用蛮力法是做不出来的(等死你),我用数学方法推出一个公式,其时间效率属于deta(n的平方) ,n为数字的最高位数位数,这里是10的平方,即100,请大家思考一下还有没有更高的算法呢?

回复列表 (共17个回复)

沙发

n方怎么来的?

板凳

原来看错了题目,重新写了个程序,分布计算一段区间之间含7的数的个数:
2008080801---2008080808
2008080001---2008080800
2008000001---2008080000
2000000001---2008000000
1------------2000000000
这个程序对不含7的数字都有效.
#include<iostream>
using namespace std;
const int n=2008080808;

int power(int k)
{
    int i;
    int temp=1;
    for(i=0;i<k-1;i++)
    {
        temp*=9;
    }
    return temp;
}

int f(int l,int t,int k)
{
    int flag=l/(t/10);
    int temp;
    if(k==1)
    {
        if(flag<7)
        {
            temp=0;
        }
        else
        {
            temp=1;
        }
    }
    else
    {
        if(flag<7)
        {
            temp=l-flag*power(k);
        }
        else if(flag>7)
        {
            temp=l-(flag-1)*power(k);
        }
        else
        {
            temp=l-flag*power(k)+1;

        }
    }
    return temp;
}

int main()
{
    int sum=0;
    int t=10;
    int m=n;
    int l;
    int k=1;
    while(t<m&&t<1000000000)
    {
        if(m%t!=0)
        {
            l=m%t;
            sum+=f(l,t,k);
            m-=l;
        }
        t*=10;
        k++;        
    }
    sum+=f(m,t,k);
    cout<<sum<<endl;
    return 0;
}

3 楼

这不是一道概率演算题吗?
先求出各位数都不出现 7 的数量,然后用总数减去该值即可。
不知道是不是我理解错了你的意思?

4 楼

先计算从1到2000000000之间有多少个数不含有数字7,再计算从2000000001到2008080808之间有多少个数含有数字7。

5 楼

10 * 10

6 楼

我记得好像是谁说的不记得了,好像是值为 9进制的(20070707)

7 楼

2008080808中含有7的数字确实不好数
不过不含7的数就太好数了,最后用2008080808-不含7的个数。
当最高为为0或者1,时就分别有9的9次方个
当最高三位为200,第四高位为1——6时就分别有9的6次方个
当最高五位为20080时,第六高位为1——6时就分别9的4次方个
。。。。。。。。。。。。

8 楼


分析数字位,
提示 十位上 7 出现的次数由个位和其他更高位决定。

176
十位 7 的出现规律是
百位0:
  70-79
百位1:
  70-76

该算法时间复杂度小于O(N) 大于 O(logN) 比蛮力法要好。

9 楼

/* 程序输入一个数,找出0-该数之间所有含有7的个数 */
# include <stdio.h>
# include <string.h>
# include <stdlib.h>


long long
xpow (int n, int pow)
{
  long long val = n;

  if (pow == 0)
    return (1);

  while (-- pow > 0)
    val *= n;

  return (val);
}

long long
find_not_seven (char *s)
{
  long long total = 0;
  int len;
  char c;

  if (!*s)
    return (0);

  len = strlen (s) - 1;

  c = '0';
  while (c < *s) {
    if (c != '7')
      total += xpow (9, len);
    c ++;
  }
  total += find_not_seven (++s);

  return (total);
}

static long long
baoli (char *s)
{
  char buf[24];
  long long x = 0;
  long long int  cnt = 0;
  long long val;

  val = atoll (s);
  while (x < val) {
    sprintf (buf, "%lld", x);
    if (strchr (buf, '7') == NULL)
      cnt ++;
    x ++;
  }

  return (cnt);
}

/* 2008080808 */
int
main (int c, char **v)
{
  char *s = v[1];

  /* 程序试图找出所有不含7的所有的个数 */
  printf ("find7 -> %lld\n", find_not_seven (s));
  printf ("baoli -> %lld\n", baoli (s));

  return (0);
}

10 楼

0-9    7
00-99    7X和X7    含7的整数有10+9=10*10-9*9=19个
000-999    百位为0--6,8,9时,9*(00-99的含7的个数)+100(百位是7的数),
    有10*10*10-9*9*9
同理0000-9999为千位为0--6,8,9时,9*(000-999的含7的个数)+1000(千位含7的数)
从0-9到0000-9999,可以得出10的n次方-9的n次方的式子,n为999.。。999的个数
在本题中是n=9,当然这只是000,000,000--999,999,999。
最后得出是1229473242

我来回复

您尚未登录,请登录后再回复。点此登录或注册