主题:编程计算从1到2008080808之间的整数有多少个含有数字7。
lxslove
[专家分:190] 发布于 2008-06-16 11:58:00
这是金山的笔试题,用蛮力法是做不出来的(等死你),我用数学方法推出一个公式,其时间效率属于deta(n的平方) ,n为数字的最高位数位数,这里是10的平方,即100,请大家思考一下还有没有更高的算法呢?
回复列表 (共17个回复)
沙发
bpttc [专家分:8790] 发布于 2008-06-19 22:49:00
n方怎么来的?
板凳
吴钩霜雪明 [专家分:0] 发布于 2008-07-22 10:59:00
原来看错了题目,重新写了个程序,分布计算一段区间之间含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 楼
lanxiaojun2 [专家分:20] 发布于 2008-07-25 14:39:00
这不是一道概率演算题吗?
先求出各位数都不出现 7 的数量,然后用总数减去该值即可。
不知道是不是我理解错了你的意思?
4 楼
qiulihua83 [专家分:0] 发布于 2008-07-29 12:13:00
先计算从1到2000000000之间有多少个数不含有数字7,再计算从2000000001到2008080808之间有多少个数含有数字7。
5 楼
zhousp20 [专家分:1290] 发布于 2008-07-29 18:07:00
10 * 10
6 楼
imjohnzj [专家分:1490] 发布于 2008-08-25 15:59:00
我记得好像是谁说的不记得了,好像是值为 9进制的(20070707)
7 楼
wyjq395 [专家分:2710] 发布于 2008-08-27 09:34:00
2008080808中含有7的数字确实不好数
不过不含7的数就太好数了,最后用2008080808-不含7的个数。
当最高为为0或者1,时就分别有9的9次方个
当最高三位为200,第四高位为1——6时就分别有9的6次方个
当最高五位为20080时,第六高位为1——6时就分别9的4次方个
。。。。。。。。。。。。
8 楼
wuliaccp [专家分:0] 发布于 2008-09-03 19:46:00
分析数字位,
提示 十位上 7 出现的次数由个位和其他更高位决定。
176
十位 7 的出现规律是
百位0:
70-79
百位1:
70-76
该算法时间复杂度小于O(N) 大于 O(logN) 比蛮力法要好。
9 楼
ivhb [专家分:0] 发布于 2008-09-06 00:44:00
/* 程序输入一个数,找出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 楼
jayzhu [专家分:0] 发布于 2008-09-08 16:57:00
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
我来回复