1到n中1的个数

#include <stdio.h>
#include <string.h>

// 1到n中含有多少个1
// 或者,1到n中含有多少个x
int getN_good(int n, int x)
{
	int i = 1;
	int c2=0; // 总计数
	
	while(n >= i) // n=12345, i=100 
	{
		int c1=0; //分计数 
		int pre = n/(i*10)*(i*10);  // pre=12000 
		int tail = n%i;       // tail=45 
		int now = n-pre-tail;      // now=300; 
		c1 += pre/10;
		if(now > x*i)
		{
			c1 += i; 
		}else
		if (now == x*i)
		{
			c1 += (tail+1);
		}
		//
		c2 += c1;
		i*=10;
	}
	return c2;
}

// 朴素算法,n中含有多少个x
static int get1(int n, int x)
{
	if(n<=0)
		return 0;
	int count = 0;
	while(n>0)
	{
		if(n%10==x)
			count++;
		n/=10;
	}
	return count;
}
// 朴素算法,1到n中含有多少个x
int get_1(int n, int x)
{
	if(n<=0 || x<0 || x>=10)
		return -1;
	int i;
	int count = 0;
	for(i=1;i<=n; i++)
	{
		count += get1(i,x);
	}
	return count;
}

int main()
{

	int a[]={1,12,112,2345,86454357};
	int c=sizeof(a)/sizeof(int);
	int i;
	int x=1;
	for(i=0;i<c;i++)
	{
		printf("how many %d in %-5d -- %-5d\n", x, a[i], get_1(a[i], x) );
	}

	printf("\nfast:\n");
	for(i=0;i<c;i++)
	{
		printf("how many %d in %-5d -- %-5d\n",x, a[i], getN_good(a[i], x) );
	}
	
	printf("\n\n");
	x=6;
	for(i=0;i<c;i++)
	{
		printf("how many %d in %-5d -- %-5d\n", x, a[i], get_1(a[i], x) );
	}

	printf("\nfast:\n");
	for(i=0;i<c;i++)
	{
		printf("how many %d in %-5d -- %-5d\n",x, a[i], getN_good(a[i], x) );
	}

	return 0;
}


输出:

how many 1 in 1     -- 1    
how many 1 in 12    -- 5    
how many 1 in 112   -- 38   
how many 1 in 2345  -- 1775 
how many 1 in 86454357 -- 70932376


fast:
how many 1 in 1     -- 1    
how many 1 in 12    -- 5    
how many 1 in 112   -- 38   
how many 1 in 2345  -- 1775 
how many 1 in 86454357 -- 70932376




how many 6 in 1     -- 0    
how many 6 in 12    -- 1    
how many 6 in 112   -- 21   
how many 6 in 2345  -- 664  
how many 6 in 86454357 -- 70275624


fast:
how many 6 in 1     -- 0    
how many 6 in 12    -- 1    
how many 6 in 112   -- 21   
how many 6 in 2345  -- 664  
how many 6 in 86454357 -- 70275624

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值