题目描述:

亲们!!我们的外国友人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. Ubuntu 学习笔记

    1.   ubuntu开启root账号,设置分配很简单,只要为root设置一个root密码就行了: $ sudo passwd root 之后会提示要输入root用户的密码,连续输入root密码,再使 ...

  2. Oracle 学习笔记 常用查询命令篇

    1.查询某个用户下有多少张表 有时候很有用  select count(*) from dba_tables t where t.owner='SCOTT';

  3. Linux 下shell显示-bash-4.1$不显示用户名路径的解决方法

    Linux CentOS下shell显示-bash-4.1$不显示用户名路径的解决方法   问题描述:   CentOS下新增一个用户,登录进去之后shell脚本的信息如下:     而不是我们经常看 ...

  4. 24点C++程序实现 编程之美1.16

    解法1,对于任意输入的四个数字,给出一个24点的解法,若无解,则没有输出. 原理参照下图(编程之美原书) 代码如下,仅供参考 // 1.16.cpp : Defines the entry point ...

  5. WIN7 XP设置MTU,提升下载速度

    可能很少有雷友注意过“本机.网络”的“MTU”值对自己网络性能产生的影响.对于追求更快的下载速度来说,MTU值设置不当,就仿佛穿着高跟鞋跑步一般. MTU是什么? “MTU=最大传输单元 单位:字节” ...

  6. 去掉php框架CI默认url中的index.php

    CI默认的rewrite url中是类似这样的 例如你的CI根目录是在/CodeIgniter/下,你的下面的二级url就类似这样 http://localhost/CodeIgniter/index ...

  7. poj 3259 Wormholes(最短路 Bellman)

    题目:http://poj.org/problem?id=3259 题意:一个famer有一些农场,这些农场里面有一些田地,田地里面有一些虫洞,田地和田地之间有路,虫洞有这样的性质: 时间倒流.问你这 ...

  8. mvc源码解读(20)-controller和view之查找view

    很多时候在mvc项目中我们需要去扩展自己的视图引擎,大概看起来应该下面这个样子的: public class RazorEngineExpand : RazorViewEngine { private ...

  9. ♫【jQuery插件】图片放大镜

    JQZoom

  10. Mint Linuxubuntu 字体配置文件

    <?xml version="1.0"?><!DOCTYPE fontconfig SYSTEM "fonts.dtd"><fon ...