剑指OFFER之从1到n中出现1的次数(九度OJ1373)
题目描述:
亲们!!我们的外国友人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
解题思路:
这道题目要注意几个问题:
第一个,比如10 到15 出现几个1?是7个...数字10 12 13 14 15各出现一次,11出现两次,因此是7次。
第二个,输入的两个数,第一个数,可能比第二个大。因此如果第一个数大于第二个数要进行一次调整。
if(n>m)
swap(&n,&m);
第三个,就是这道题的主要思想。
主要思想,通过递归来求解。我们分别求出两个数含有1的个数,但是要注意,对小的的数求解时,要减1.因为如果是10到15,0到10应该含有2个1,而0到15含有8个1,如果直接相减,10的那个1就被减掉了。因此要减1求解。
char numN[MAXSIZE];
char numM[MAXSIZE];
sprintf(numN,"%d",n-1);
sprintf(numM,"%d",m);
numberOfN = getNumber(numN);
numberOfM = getNumber(numM);
printf("%dn",numberOfM-numberOfN);
算法主要思想,首先我们看最高位。把数分解,abcde就分解成bcde+1到abcde 与 1到bcde两段。比如,34567分解成4568到34567,1到4567.这样求解第一段,只需要考虑第一位,和后面几位的普通情况就行了。然后递归求第二段。
如果最高位是大于1的数。那么就分包含1的情况,和1以外的情况。
对于最高位是1的,后面无论是什么都满足情况。因此,如果高位刚好等于1,那么满足的情况更应该是后面的数字之和。举个例子,
12345,最高位为1时,满足的情况为2345种(不考虑后面的)。
numF = 0;
if(firstNum > 1)
numF = power(length-1);
else if(firstNum == 1)
numF = atoi(num+1)+1;
而22345,最高位大于1时,满足的情况为10000-19999,即10000种。
接下来,分析下最高位不是1时候,应该就是后面的个个位数为1其他位随机的数目。即,first*(lengt-1)*power(length-2),即在本例中为2*4*1000种,即11000,11001,11002,11003...21000,21002,21003,21004...即每一位为1*其他几位的随机数。此处就是4*1000.
int getNumber(const char *num){
int firstNum = *num-'0';
int length = strlen(num);
int numF,numOther,numL;
if(!num || *num < '0' || *num > '9' || *num == ' ')
return 0;
if(length == 1 && firstNum == 0)
return 0;
if(length == 1 && firstNum > 0)
return 1;
numF = 0;
if(firstNum > 1)
numF = power(length-1);
else if(firstNum == 1)
numF = atoi(num+1)+1;
numOther = firstNum*(length-1)*power(length-2);
numL = getNumber(num+1);
return numF + numOther + numL;
}
全部代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 32
int getNumber(const char *num);
int power(int length);
void swap(int *a,int *b);
int main(){
int n,m,numberOfN,numberOfM;
while(scanf("%d %d",&n,&m)!=EOF ){
if(n>m)
swap(&n,&m);
char numN[MAXSIZE];
char numM[MAXSIZE];
sprintf(numN,"%d",n-1);
sprintf(numM,"%d",m);
numberOfN = getNumber(numN);
numberOfM = getNumber(numM);
printf("%dn",numberOfM-numberOfN);
//printf("%dn",n%10 == 1?(numberOfM - numberOfN+1):(numberOfM-numberOfN));
}
return 0;
}
int getNumber(const char *num){
int firstNum = *num-'0';
int length = strlen(num);
int numF,numOther,numL;
if(!num || *num < '0' || *num > '9' || *num == ' ')
return 0;
if(length == 1 && firstNum == 0)
return 0;
if(length == 1 && firstNum > 0)
return 1;
numF = 0;
if(firstNum > 1)
numF = power(length-1);
else if(firstNum == 1)
numF = atoi(num+1)+1;
numOther = firstNum*(length-1)*power(length-2);
numL = getNumber(num+1);
return numF + numOther + numL;
}
int power(int length){
int i;
int result = 1;
for(i=0;i<length;i++){
result *= 10;
}
return result;
}
void swap(int *a,int *b){
int tmp = *b;
*b = *a;
*a = tmp;
}
/**************************************************************
Problem: 1373
User: xhalo
Language: C
Result: Accepted
Time:10 ms
Memory:916 kb
****************************************************************/
- DW Replace Open Sans:将WordPress 后台中的open-sans字体加载源从Google Fonts换为360 CDN
- Angularjs基础(三)
- 低多边形(Low-Poly)简介及相关素材分享下载
- 开发者的福音:GenerateWP 自动生成WordPress 开发相关代码
- 自定义WordPress 密码文章提示文字
- 解决WordPress文章密码保护在首页(摘要)不起作用
- WordPress 3.9+的 TinyMCE 4 编辑器增强开发
- Angularjs基础(二)
- Angularjs基础(一)
- iOS 7 Web App的初级优化之道
- Less 常用基础知识
- WooCommerce 结算页面自定义(删除/添加)表单元素
- Waves:类Material Design 的圆形波浪(涟漪)点击特效插件
- 让WooCommerce 中文网关支持PayPal 并自动按汇率进行转换
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法