题目描述:

亲们!!我们的外国友人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)的更多相关文章

  1. 剑指 Offer 43. 1~n 整数中 1 出现的次数 + 数位模拟 + 思维

    剑指 Offer 43. 1-n 整数中 1 出现的次数 Offer_43 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author ...

  2. 【剑指Offer面试编程题】题目1362:左旋转字符串--九度OJ

    题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=&qu ...

  3. 【剑指Offer面试编程题】题目1361:翻转单词顺序--九度OJ

    题目描述: JOBDU最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,&quo ...

  4. 【剑指Offer面试编程题】题目1372:最大子向量和--九度OJ

    题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但 ...

  5. 【剑指Offer面试编程题】题目1391:顺时针打印矩阵--九度OJ

    题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2 ...

  6. 【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ

    题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点 ...

  7. 【剑指Offer面试编程题】题目1520:树的子结构--九度OJ

    题目描述: 输入两颗二叉树A,B,判断B是不是A的子结构. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1&l ...

  8. 剑指OFFER之二叉树中和为某一值的路径(九度OJ1368)

    题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 输入: 每个测试案例包括n+1行: 第一行为2 ...

  9. 剑指OFFER之栈的压入、弹出序列(九度OJ1366)

    题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...

  10. 剑指OFFER之第一个只出现一次的字符(九度OJ1283)

    题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...

随机推荐

  1. PHP的(Thread Safe与Non Thread Safe)

    在安装xdebug到时候你会有有TS和NTS版本的选择,在以前还有VC6和VC9的版本.如果你没有根据你目前的服务器的状况选择对应的版本的话,那么xdebug是安装不成功的. 一.如何选择 php5. ...

  2. PHP+Mysql无限分类的方法汇总

    无限分类是个老话题了,来看看PHP结合Mysql如何实现.第一种方法这种方法是很常见.很传统的一种,先看表结构表:categoryid int 主键,自增name varchar 分类名称pid in ...

  3. bugumongo--ConnectToMongoDB

    连接MongoDB 在能够对MongDB进行操作之前,需要使用BuguConnection连接到MongoDB数据库.代码如下: BuguConnection conn = BuguConnectio ...

  4. 转载:C++ vector 类学习笔记

    声明:本文转载自http://blog.csdn.net/whz_zb/article/details/6827999 vector简介 vector是STL中最常见的容器,它是一种顺序容器,支持随机 ...

  5. JAVA并行框架学习之ForkJoin

    当硬件处理能力不能按照摩尔定律垂直发展的时候,选择了水平发展,多核处理器已经广泛应用.未来随着技术的进一步发展,可能出现成百上千个处理核心,但现有的程序运行在多核心处理器上并不能得到较大性能的提升,主 ...

  6. uva1658 admiral

    费用流. 裸的拆点最小费用流,一跑就行. 核弹预警,为何wa20多发.build函数一定要返回true...... 太可怕了 #include<cstdio> #include<al ...

  7. unity3d游戏物体跟着鼠标方向移动

    效果:当点击鼠标左键时,游戏对象会朝鼠标点击的方向移动,类似魔兽争霸一样. 思路:把鼠标的坐标转化成世界坐标(鼠标默认是屏幕坐标),然后当点击鼠标时,物体将朝着鼠标的世界坐标方向移动. 如果你看到这的 ...

  8. android 三目运算符 运用错误

    /************************************************************************** * android 三目运算符 运用错误 * 说 ...

  9. 如何从Linux源码获知版本信息

    /*************************************************************************** * 如何从Linux源码获知版本信息 * 声明 ...

  10. POJ3281 Dining 最大流

    题意:有f种菜,d种饮品,每个牛有喜欢的一些菜和饮品,每种菜只能被选一次,饮品一样,问最多能使多少头牛享受自己喜欢的饮品和菜 分析:建边的时候,把牛拆成两个点,出和入 1,源点向每种菜流量为1 2,每 ...