剑指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出现的次数。
- 样例输入:
- 样例输出:
解题思路:
这道题目要注意几个问题:
第一个,比如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-);
sprintf(numM,"%d",m);
numberOfN = getNumber(numN);
numberOfM = getNumber(numM);
printf("%d\n",numberOfM-numberOfN);
算法主要思想,首先我们看最高位。把数分解,abcde就分解成bcde+1到abcde 与 1到bcde两段。比如,34567分解成4568到34567,1到4567.这样求解第一段,只需要考虑第一位,和后面几位的普通情况就行了。然后递归求第二段。
如果最高位是大于1的数。那么就分包含1的情况,和1以外的情况。
对于最高位是1的,后面无论是什么都满足情况。因此,如果高位刚好等于1,那么满足的情况更应该是后面的数字之和。举个例子,
12345,最高位为1时,满足的情况为2345种(不考虑后面的)。
numF = ;
if(firstNum > )
numF = power(length-);
else if(firstNum == )
numF = atoi(num+)+;
而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-'';
int length = strlen(num);
int numF,numOther,numL;
if(!num || *num < '' || *num > '' || *num == '\0')
return ;
if(length == && firstNum == )
return ;
if(length == && firstNum > )
return ;
numF = ;
if(firstNum > )
numF = power(length-);
else if(firstNum == )
numF = atoi(num+)+;
numOther = firstNum*(length-)*power(length-);
numL = getNumber(num+);
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-);
sprintf(numM,"%d",m);
numberOfN = getNumber(numN);
numberOfM = getNumber(numM);
printf("%d\n",numberOfM-numberOfN);
//printf("%d\n",n%10 == 1?(numberOfM - numberOfN+1):(numberOfM-numberOfN));
}
return ;
}
int getNumber(const char *num){
int firstNum = *num-'';
int length = strlen(num);
int numF,numOther,numL;
if(!num || *num < '' || *num > '' || *num == '\0')
return ;
if(length == && firstNum == )
return ;
if(length == && firstNum > )
return ; numF = ;
if(firstNum > )
numF = power(length-);
else if(firstNum == )
numF = atoi(num+)+; numOther = firstNum*(length-)*power(length-); numL = getNumber(num+); return numF + numOther + numL;
}
int power(int length){
int i;
int result = ;
for(i=;i<length;i++){
result *= ;
}
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
****************************************************************/
剑指OFFER之从1到n中出现1的次数(九度OJ1373)的更多相关文章
- 剑指 Offer 43. 1~n 整数中 1 出现的次数 + 数位模拟 + 思维
剑指 Offer 43. 1-n 整数中 1 出现的次数 Offer_43 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author ...
- 【剑指Offer面试编程题】题目1362:左旋转字符串--九度OJ
题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=&qu ...
- 【剑指Offer面试编程题】题目1361:翻转单词顺序--九度OJ
题目描述: JOBDU最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,&quo ...
- 【剑指Offer面试编程题】题目1372:最大子向量和--九度OJ
题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但 ...
- 【剑指Offer面试编程题】题目1391:顺时针打印矩阵--九度OJ
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2 ...
- 【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ
题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点 ...
- 【剑指Offer面试编程题】题目1520:树的子结构--九度OJ
题目描述: 输入两颗二叉树A,B,判断B是不是A的子结构. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1&l ...
- 剑指OFFER之二叉树中和为某一值的路径(九度OJ1368)
题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 输入: 每个测试案例包括n+1行: 第一行为2 ...
- 剑指OFFER之栈的压入、弹出序列(九度OJ1366)
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...
- 剑指OFFER之第一个只出现一次的字符(九度OJ1283)
题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...
随机推荐
- 完全掌握Android Data Binding
转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0603/2992.html 来源 https://github.com/L ...
- 【算法】 输入n 输出一个n*n的zigzag矩阵 利用c++实现
int main() { int N; cin>>N; int **a = new int *[N]; ) ;//如果没有申请到空间 ;i<N;i++) { a[i]= new in ...
- IIS会话过期的问题/WCF日志管理
http://technet.microsoft.com/zh-cn/library/cc725624(v=ws.10).aspx http://msdn.microsoft.com/zh-cn/li ...
- ARM7ldr指令与ldr伪指令
ldr伪指令的第二个操作数之前有个=,意思是第一个操作书 = 第二个操作数,相当明了 核心就在于对于用.word指令在.text段里另外定义一段内存,用ldr r0,[pc + x(可以算出.text ...
- 条件与(&&)和逻辑与(&)以及条件或(||)和逻辑或(|)区别
条件与(&&)和逻辑与(&)以及条件或(||)和逻辑或(|)区别在于它们的运算结果是不相同的. 条件与(&&)和条件或(||)采用的是所谓的"短路规则 ...
- 在C++中调用DLL中的函数
如何在C++中调用DLL中的函数 应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0在VC\bin目录下 ...
- Angularjs中input的指令和属性
建议添加 novalidate属性(可无值)到form标签上,这样可以保证在表单不合法的情况下阻止浏览器继续提交数据. 可以给表单元素 input 添加 required 属性(可无值),让该表单成为 ...
- sencha touch tabsidebar 源码扩展
先上图看效果 没错,这是一个sencha touch 项目,而这里的右边推出效果(下文叫做tabsiderbar),使用插件tabsiderbar来扩展的. 插件js下载地址:http://www.m ...
- I.MX6 Android Linux shell MMPF0100 i2c 获取数据
#!/system/bin/busybox ash # # I.MX6 Android Linux shell MMPF0100 i2c 获取数据 # 说明: # 本文主要记录通过shell脚本来获取 ...
- jquery 上传空间uploadify使用笔记
基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,删除已上传文件. 要求使用jquery1.4或以上版本,flash player 9.0.24以上. 有两个 ...