51nod 1009:数字1的数量
输入N(1 <= N <= 10^9)
输出包含1的个数
12
5
没怎么学过数位dp,打算好好搞一下~
dp[x]代表1~10^x-1 中1出现的次数,当然0~9出现的次数都是这个。
然后从后往前扫,假设该位的值是digit,那么如果digit大于1就加上digit*dp[len-1]。len代表当前扫描的长度。
然后还有就是以1开头的pow(10,len-1),后面的数字任意,会发现这个时候算重复了反而是正确的,因为比方说11计算了两次,但也因为11有两个1,所以从不同的角度计算出来的11就不用考虑重复的情况了。
如果digit等于1,有一些麻烦,那么就等于原来的数量result(把它想象成在以1开头的数里面,这里面1的数量就是原来的result) + dp[len-1]这个数量,剩下的就是有多少个以1开头的数字,这个头还没有算,而这个数量就是除了1开头剩下的tail的数量。
好比141,到第三个1的时候,实际上已经算出了1~41的1的数量,那我把这个数量想象成是在100~141里面除开开头的1的数量,加上42个开头的1,这个还没算。然后还有的就是1~99的1的数量。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; typedef long long ll; ll s;
ll dp[20]; void init()
{
memset(dp, 0, sizeof(dp)); int i, j;
for (i = 1; i <= 19; i++)
{
for (j = 0; j <= 9; j++)
{
dp[i] = dp[i - 1] * 10 + pow(10, i - 1);
}
}
} ll count(ll x)
{
ll result = 0;
ll len = 0;
ll digit = 0;
ll radix = 1;
ll tail = 0;
while (x != 0)
{
digit = x % 10;
x = x / 10; ++len; if (digit > 1)
{
result += radix + digit*dp[len-1];//radix就代表10的多少多少次方,这个时候重复算反而是对的
}
else if (digit == 1)
{
result += tail + 1 + dp[len-1];//+1是代表取的那个整数
}
tail = tail + digit*radix;
radix *= 10;
}
return result;
} int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); init(); cin >> s;
cout << count(s)<<endl; //system("pause");
return 0;
}
51nod 1009:数字1的数量的更多相关文章
- 51nod 1009 数字1的数量
1009 数字1的数量 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5 ...
- 51nod 1009 数字1的数量 数位dp
1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1 ...
- 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...
- 51nod 1009 数字1的数量(数位dp模板)
给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. 数位dp的模板题 ...
- 51Nod 1009:1009 数字1的数量 (思维)
1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的 ...
- 51nod 1042数字0-9的数量
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19 ...
- [51 nod]1009 数字1的数量
1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如: ...
- 1001 数组中和等于K的数对 1002 数塔取数问题 1003 阶乘后面0的数量 1004 n^n的末位数字 1009 数字1的数量
1001 数组中和等于K的数对 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K ...
- 51nod 1042 数字0-9的数量 数位dp
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-1 ...
- 1009 数字1的数量 数位dp
1级算法题就这样了,前途渺茫啊... 更新一下博客,我刚刚想套用数位dp的模板,发现用那个模板也是可以做到,而且比第二种方法简单很多 第一种方法:我现在用dp[pos][now]来表示第pos位数字为 ...
随机推荐
- mysql yum源安装极速
mysql yum源地址:https://dev.mysql.com/downloads/repo/yum/ 随便找个最新的不管你是要装任何个历史版本他都可以,后面我会介绍: 安装第一步预置环境清理: ...
- hutoolJava工具类的使用
前言 安装 友情开源项目 Hutool相关博客(软文) 捐赠使用公开 核心(Hutool-core) 克隆 支持泛型的克隆接口和克隆类 类型转换 类型转换工具类-Convert 自定义类型转换-Con ...
- Java基础 -4.4
For循环 for循环也是一种常规的使用结构 public static void main(String[] args) { for(定义循环的初始值;循环判断;修改循环条件) { 循环语句的执行; ...
- Elasticsearch 如何使用RESTful API
所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch .事实上,正如你所看到的 ...
- java记录1--接口
接口(interface)定义:抽象方法和常量值的集合.本质上讲,接口是一种特殊的抽象类 ps:1.接口中定义的属性必须是public static final 的,定义的方法必须是public ab ...
- JVM,JRE,JDK
JVM (Java Virtual Machine) : Java虚拟机,运行所有Java程序的假象计算机,是Java程序的运行环境,跨平台性由JVM实现. JRE (Java Runtime Env ...
- ‘.vue’文件(非常重要)
‘.vue’文件 Vue自定义了一种后缀名名字为.vue文件,它将html, js, css 整合成一个文件,和里面 template script style三个区别分别依次对应. 1 2 3 4 ...
- 为什么很多 Android 程序喜欢在存储卡根目录建文件夹来存储数据而不是 Android/data 目录下?
知乎回答. http://www.zhihu.com/question/19866689 pansz,欢迎评论 知乎用户.弓长.知乎用户 赞同 这个道理很简单:因为没人管啊.你乱存放文件,在a ...
- 「SP10628 COT - Count on a tree」
主席树的综合运用题. 前置芝士 可持久化线段树:其实就是主席树了. LCA:最近公共祖先,本题需要在\(\log_2N\)及以内的时间复杂度内解决这个问题. 具体做法 主席树维护每个点到根节点这一条链 ...
- Jmeter JDBC配置
前提条件,驱动包mysql-connector-java-5.1.38-bin.jar要放到本机Java路径:C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext ...