google一道面试题的解答,谁能帮我看懂这个程序C代码吗??

azhen 2008-04-04 11:08:36
Consider a function which, for a given whole number n, returns the number of ones required when writing out all numbers between 0 and n.

For example, f(13)=6. Notice that f(1)=1. What is the next largest n such that f(n)=n?

e.g.
f(13)=6,
because the number of "1" in 1,2,3,4,5,6,7,8,9,10,11,12,13 is 6. (1, 11, 12, 13)

tks
现在要我们写一个函数,计算4,000,000,000以内的 最大的那个f(n)=n的值,要求程序能在100ms里面运行完毕,我在网上查解答,只发现下面的代码可以很出色的运行得到正确结果,但是一直没看明白他的具体思路,大家能帮我解释一下吗,非常的谢谢!

下面的代码非常出色,运行起来20ms就能解决问题,大家一起读读吧,说说心得:)
#include <windows.h>
#include <stdlib.h>

int f(int n);
int count1(int n);
int cal(unsigned int number,int nwei,int count1,unsigned int ncount);

int gTable[10];
const unsigned int gMAX = 4000000000L;

int main(int argc, char* argv[])
{
int i;
unsigned int n=1;
unsigned int ncount = 0;
int nwei = 0;
int ncount1;

/*if(argc>1)
{
n = atoi(argv[1]);
ncount = f(n);
printf("f(%d) = %d\n",n,ncount);
}*/

int beginTime=GetTickCount();
int endTime;
//init gTable
for(i=0;i <10;++i)
{
n *= 10;
gTable[i] = f(n-1);
}

n=0;
nwei = 0;
ncount1 = 0;
while(n <gMAX)
{
unsigned int temp;

temp = 1;

ncount =cal(n,nwei,ncount1,ncount);
for(i=0;i <nwei;++i)
temp *= 10;
n += temp;
if( (n/temp)/10 == 1)
++nwei;
ncount1 = count1(n);
}

endTime=GetTickCount();
endTime-=beginTime;

printf("time: %d ms\n",endTime);
return 0;
}


int f(int n)
{
int ret = 0;
int ntemp=n;
int ntemp2=1;
int i=1;
while(ntemp)
{
ret += (((ntemp-1)/10)+1) * i;
if( (ntemp%10) == 1 )
{
ret -= i;
ret += ntemp2;
}
ntemp = ntemp/10;
i*=10;
ntemp2 = n%i+1;
}
return ret;
}

int count1(int n)
{
int count = 0;
while(n)
{
if( (n%10) == 1)
++count;
n /= 10;
}
return count;
}

int cal(unsigned int number,int nwei,int count1,unsigned int ncount)
{
int i,n=1;
unsigned int maxcount;
if(nwei==0)
{
ncount += count1;
if(number == ncount)
{
printf("f(%d) = %d \n",number,number);
}
return ncount;
}
for(i=0;i <nwei;++i)
n *= 10;
maxcount = ncount + gTable[nwei-1];
maxcount += count1*n;
if(ncount > (number + (n-1)) )
{
return maxcount;
}
if(maxcount < number)
{
return maxcount;
}
n /= 10;
for(i=0;i <10;++i)
{
if(i==1)
ncount = cal(number+i*n,nwei-1,count1+1,ncount);
else
ncount = cal(number+i*n,nwei-1,count1,ncount);
}
return ncount;
}
...全文
372 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gotofly21 2008-04-08
  • 打赏
  • 举报
回复
很简单,概率问题,10个数字出现概率都是10%,
因此一位数出现1次,两位数出现100*2/10=20次
3位数出现1000*3/10=300次

比如输入40001
// 4个9999 10000~19999 40001
f(40001)=4*(10000*4/10)+1*10000 + 1
bjjfirst 2008-04-08
  • 打赏
  • 举报
回复
好像,速度不行啊。
惭愧
bjjfirst 2008-04-08
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <iostream>


using namespace std;

int ones(unsigned int n)
{
int sum = 0;
while( n > 0)
{
int singledigit = n%10;

if (singledigit == 1)
++sum;

n = n/10;
}
return sum;
}

const unsigned long max_value = 4E10L;
int _tmain(int argc, _TCHAR* argv[])
{
int sum = 0;
for (int i =1;i < max_value;i++)
{
int temp = ones(i);
if (temp > 0)
sum+= temp;
if (sum == i)
std::cout << i << std::endl;
}

return 0;
}


nosafer 2008-04-06
  • 打赏
  • 举报
回复
老实说这个解法不怎么地。。。。。。。
jinwei1984 2008-04-06
  • 打赏
  • 举报
回复
学习!
wanghao111 2008-04-05
  • 打赏
  • 举报
回复
交流群 C++ java 36414176
maryjeck 2008-04-05
  • 打赏
  • 举报
回复
有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。比如f(13)=6,现在f(1)=1,问下一个最大的f(n)=n的n是什么?

为什么f(13)=6, 因为1,2,3,4,5,6,7,8,9,10,11,12,13.数数1的个数,正好是6.
aizhuhui 2008-04-05
  • 打赏
  • 举报
回复
在哪见过..
大写的池 2008-04-05
  • 打赏
  • 举报
回复
题意看不懂,(与英语无关)可以解释一下吗?
fallening 2008-04-04
  • 打赏
  • 举报
回复
楼上说下思路
程序没有注释
oo 2008-04-04
  • 打赏
  • 举报
回复
发两个帖子?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧