pata1049

题目
pata1049
题目思路
对于任一数字如654321,在计算1的数量时可以将其拆分为,1至60000,600001至650000,650001至654000,654001至654300,654301至654320,654321这几部分来计算,由于高位数字均没有1,则可简化为1至600000,1至50000,1至4000,1至300,1至20,1中1的数量。因此,可以先计算从0到9、99、999等里1的数量s[n],而对于首数字大于1的数,例如30,300,3000之类可用3*s[i]+10的p次方(p为30,300,3000里0的数量,即用于表示1开头的数字数)。对于首数字为1的数,拆分时需要注意在总数中加上1后所跟数字的数值+1,用以表示在拆分时忽略掉的首位的1。
参考代码

#include<iostream>
#include<cstring>

using namespace std;
int count(char c,int p,int n,int s[]);
int change(char c[]);

int main()
{
	
	char c[12];
	int s[12];
	int p=1,t=0,n=0;
	
	s[1]=1;
	for(int i=2;i<12;i++)
	{
		p*=10;
		s[i]=s[i-1]*10+p;//s[i]表示从0到i个9之间有多少个1 
	}
	scanf("%s",c);
	p=1;	
	for(int i=0;i<strlen(c)-1;i++)//位数 
	{
		p*=10;
		n+=1;
	}
	for(int i=0;i<strlen(c);i++)
	{
		t+=count(c[i],p,n,s);
		if(c[i]=='1')
			t+=change(c)%p+1;
		p/=10;
		n-=1;
	}
	printf("%d",t);	
	
	return  0;
	
}

int count(char c,int p,int n,int s[])//从0到c*10的n次方之间有多少1 
{
	int t=0;
	
	if(c>'1')
		t+=p;
	if(n>0)	
		t+=(c-'0')*s[n]; 
	
	return t;
}

int change(char c[])
{
	int a=0,p=1;
	
	for(int i=strlen(c)-1;i>=0;i--)
	{
		a+=(c[i]-'0')*p;
		p*=10;
	}
	
	return a;
}
发布了27 篇原创文章 · 获赞 0 · 访问量 374

猜你喜欢

转载自blog.csdn.net/zz73zz76/article/details/104296447