码迷,mamicode.com
首页 > 其他好文 > 详细

51mod1009

时间:2018-07-14 16:28:40      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:return   mod   正整数   没有   思路   else   int   出现   ++   

给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
 
例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
Input
输入N(1 <= N <= 10^9)
Output
输出包含1的个数
Input示例
12
Output示例
5
思路:一看到这道题就想到了记忆化搜索,奈何太久没打过了,忘记了太多要素,因此被此题卡了四个多小时。。。。。吐血啊
#include<stdio.h>
#include<string.h>
int dis[12];
int lg,len;
int s[12];
int dp[12][2];
int check(int a){
	int i=0;
	if(a<0)
	return 0;
	int ans=0;
	for(i=0;i<=a;i++)
	ans+=dis[i]*s[i];
	//printf("%d %d\n",a,ans);
	return ans;
}
int dfs(int pos,int lg){
	if(pos<0)
	return 0;
	int num=lg?dis[pos]:9;
//	printf("num=%d\n",num);
	if(!lg&&dp[pos][lg]!=-1)
	return dp[pos][lg];
	
	int i,j;
	int ans=0;
	
	for(i=0;i<=num;i++){//计算当第pos位为i时时,后面pos-1位有多少种情况; (当为i时,计算的范围为i*10^(pos)----(i+1)*10^(pos)-1) 
		if(i==1){
			if(lg&&i==num)
			{ans=ans+check(pos-1)+1+dfs(pos-1,lg&&(i==num));//0---check(pos-1),所以要加一 
				
				//printf("a%d %d %d\n",pos,i,ans);
			}
			else
			{
				ans=ans+s[pos]+dfs(pos-1,lg&&(i==num));//当此位为1时,它没有被限制,那么可以分解成10000+(0---9999)(假设当前有五位) 
				//printf("b%d\n",ans);//0---9999的每一个数都可以在前面加一个 。 
			}
		}
		else
		{ans+=dfs(pos-1,lg&&(i==num));
	//	printf("c%d\n",ans);
		}
	}
//	printf("%d %d\n",pos,ans);
	if(!lg)
	dp[pos][lg]=ans;
	return ans;
}
int main(){
	int n;
	len=0;
	scanf("%d",&n);
	int i;
	s[0]=1;
	for(i=1;i<=9;i++)
	s[i]=s[i-1]*10;
	while(n){
		dis[len++]=n%10;
		n=n/10;
	}
	memset(dp,-1,sizeof(dp));
	printf("%d\n",dfs(len-1,1));
	return 0;
}

  

51mod1009

标签:return   mod   正整数   没有   思路   else   int   出现   ++   

原文地址:https://www.cnblogs.com/cglongge/p/9309482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!