题目1373:整数中1出现的次数(从1到n整数中1出现的次数)-九度

本文介绍了一个算法问题,即计算指定范围内所有整数中数字1出现的总次数。通过分析输入数字的每一位,并利用递归方法,文章提供了一种有效解决方案。
题目描述:
亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他。问题是:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
输入:
输入有多组数据,每组测试数据为一行。
每一行有两个整数a,b(0<=a,b<=1,000,000,000)。
输出:
对应每个测试案例,输出a和b之间1出现的次数。
样例输入:
0 5
1 13
21 55
31 99
样例输出:
1
6
4

7

推荐指数:※※

来源:http://ac.jobdu.com/problem.php?pid=1373

这道题和http://blog.youkuaiyun.com/zhu_liangwei/article/details/9207949题类似。要注意:

1.a,b之间的大小不一定

2.判断a.b大小的时候要小心。(特别是使用字符串表示数字的同学)a,b包含的1的个数不一定可以准确反应a.b的大小。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
const int N=20;
long long  count_ones(char *a,int index){
	long long left=0,right=0,i;
	long long  sum=0,len=strlen(a);
	for(i=0;i<index;i++){
		left=left*10+a[i]-'0'; 
	}
	for(i=index+1;a[i]!='\0';i++){
		right=right*10+a[i]-'0';
	}
    long long b=(long long)pow(10,len-index-1);
	if(a[index]=='0')
		sum=left*b;
	else if(a[index]=='1'){
		sum=left*b+right+1;
	}
	else{
		sum=(left+1)*b;
	}
	if(index<len-1)
		sum+=count_ones(a,index+1);
	return sum;
}
long long  count_num(char *a){
    long long  sum=0,i;
    for(i=0;a[i]!='\0';i++){
        if(a[i]=='1')
            sum++;
    }
    return sum;
    
}
int main(){
    char a[N],b[N];
    while(scanf("%s%s",a,b)!=EOF){
		long long  tmp;
        long long n1=count_ones(a,0);
        long long n2=count_ones(b,0);
		if(strlen(a)>strlen(b)||(strlen(a)==strlen(b)&&strcmp(a,b)>0)){
		   tmp=count_num(b);
           printf("%lld\n",n1-n2+tmp);
		}
		else{
			 tmp=count_num(a);
		     printf("%lld\n",n2-n1+tmp);
		}
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值