51nod 1042数字0-9的数量
两个数a,b(1 <= a <= b <= 10^18)
输出共10行,分别是0-9出现的次数
10 19
1
11
1
1
1
1
1
1
1
1
没什么思路 看了题解前半部分 说跟51nod上一道问1的个数的题很像
题目在这里
输入N(1 <= N <= 10^9)
输出包含1的个数
12
5
感觉思路真的挺巧妙的 统计各个位数是1的数
比如:12。个位上可能出现1的数为1,11(一共2个),十位上可能出现1的个数为10,11,12(一共3个),加一起正好是5。(至于11是否重复的问题,还是再理解一下上面的做法,这个做法只考虑了每一位出现1的数,11在个位上算和在十位上算是不一样的,所以并没有重复)。
21905:
个位:它出现1的数为:1 ~ 21901,一共 2190 - 0 + 1 = 2191
十位:它出现1的数为:1x ~ 2181x (x 从0到9)一共:(218 - 0 + 1)*10 = 2190
百位:它出现1的数为:1xx ~ 211xx ,一共:(21 - 0 + 1)* 100 = 2200
千位:它出现1的数为:1xxx ~ 11xxx 和 21000 ~ 21905 ,那么很明显,这个情况就比较特殊了,为什么呢?下面再说,我们先计数,一共:(1 - 0 + 1)*1000 + (905 - 0 + 1)= 2000 + 906 = 2906
万位:它出现1的数为:1xxxx ~ 1xxxx,一共:10000
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cstring>
#include <cmath>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
ll a, b;
ll ansa[10], ansb[10];
ll cntnum(int num, ll n)
{
ll ans = 0, tmp = n;
long long tnum = 1;
while(tmp){
long long t = tmp % 10;
if(t < num && num){
ans += n / (tnum * 10) * tnum;
}
else if(t == num){
if(num){
ans += n / (tnum * 10) * tnum;
ans += (n % tnum) + 1;
}
else ans++;
}
else{
if(num)ans += (n / (tnum * 10) + 1) * tnum;
else ans++;
}
tnum *= 10;
tmp /= 10;
}
return ans;
}
ll cnt0(ll n)
{
ll i = 1;
ll ans = 0;
ll before = 0, cur = 0, after = 0;
while((n / i)){
cur = (n / i) % 10;
before = n / (i * 10);
after = n - (before * 10 + cur) * i;
if(cur == 0){
ans += (before - 1) * i + after + 1;
}
else{
ans += before * i;
}
i *= 10;
}
return ans;
}
int main()
{
while(scanf("%I64d%I64d", &a, &b) != EOF){
memset(ansa, 0, sizeof(ansa));
memset(ansb, 0, sizeof(ansb));
ansa[0] = cnt0(a - 1);
ansb[0] = cnt0(b);
for(int i = 1; i <= 9; i++){
ansa[i] = cntnum(i, a - 1);
ansb[i] = cntnum(i, b);
//cout<< ansb[i] - ansa[i]<<endl;
}
/*while(a){
ansa[a % 10]--;
a /= 10;
}*/
for(int i = 0; i <= 9; i++){
cout<< ansb[i] - ansa[i]<<endl;
}
}
return 0;
}
新改的这份代码应该会更容易理解一点
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cstring>
#include <cmath>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
ll a, b;
ll ansa[10], ansb[10];
/*ll cntnum(int num, ll n)
{
ll ans = 0, tmp = n;
long long tnum = 1;
while(tmp){
long long t = tmp % 10;
if(t < num){
ans += n / (tnum * 10) * tnum;
}
else if(t == num){
ans += n / (tnum * 10) * tnum;
ans += (n % tnum) + 1;
}
else{
ans += (n / (tnum * 10) + 1) * tnum;
}
tnum *= 10;
tmp /= 10;
}
return ans;
}*/
ll cnt0(ll n)
{
ll i = 1;
ll ans = 0;
ll before = 0, cur = 0, after = 0;
while((n / i)){
cur = (n / i) % 10;
before = n / (i * 10);
after = n - (before * 10 + cur) * i;
if(cur == 0){
ans += (before - 1) * i + after + 1;
}
else{
ans += before * i;
}
i *= 10;
}
return ans;
}
ll cntnum(int num, ll n)
{
ll i = 1;
ll ans = 0;
ll before = 0, cur = 0, after = 0;
while((n / i)){
cur = (n / i) % 10;
before = n / (i * 10);
after = n - (before * 10 + cur) * i;
if(cur == num){
ans += before * i + after + 1;
}
else if(cur < num){
ans += before * i;
}
else{
ans += (before + 1) * i;
}
i *= 10;
}
return ans;
}
int main()
{
while(scanf("%I64d%I64d", &a, &b) != EOF){
memset(ansa, 0, sizeof(ansa));
memset(ansb, 0, sizeof(ansb));
ansa[0] = cnt0(a - 1);
ansb[0] = cnt0(b);
for(int i = 1; i <= 9; i++){
ansa[i] = cntnum(i, a - 1);
ansb[i] = cntnum(i, b);
//cout<< ansb[i] - ansa[i]<<endl;
}
/*while(a){
ansa[a % 10]--;
a /= 10;
}*/
for(int i = 0; i <= 9; i++){
cout<< ansb[i] - ansa[i]<<endl;
}
}
return 0;
}
51nod 1042数字0-9的数量的更多相关文章
- 51nod 1042 数字0-9的数量 数位dp
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-1 ...
- 51nod 1042 数字0-9的数量
给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. Inp ...
- (数位DP)51NOD 1042 数字0-9的数量
给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. 输入 ...
- 51nod- 【1042 数字0-9的数量 】
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 题目: 1042 数字0-9的数量 基准时间限制:1 ...
- 1042 数字0-9的数量 1050 循环数组最大子段和 1062 序列中最大的数 1067 Bash游戏 V2 1092 回文字符串
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次 ...
- 51 Nod1042 数字0到9的数量
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19 ...
- 51nod 1042 数位dp
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131 ...
- 字符串怎么换行 || 字符串中使用单引号时应该怎么写 || 保留两位小数 || 数字0在if中的意思是false || 什么情况下会会报undefined || null和undefined的区别 ||
换行的字符串 "This string\nhas two lines" 字符串中使用单引号时应该怎么写 'You\'re right, it can\'t be a quote' ...
- 【编程题目】n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始
第 18 题(数组):题目:n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始,每次从这个圆圈中删除第 m 个数字(第一个为当前数字本身,第二个为当前数字的下一个数字).当一个数字删除后, ...
随机推荐
- springboot+swagger2案例
1.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- java stream Api
Stream的简单使用 Stream的使用分为两种类型: Intermediate,一个Stream可以调用0到多个Intermediate类型操作,每次调用会对Stream做一定的处理,返回一个新的 ...
- linux 实时查看Tomcat日志信息
cd /../tomcat/logs 进入tomcat/logs/文件夹下 # tail -f catalina.out
- grid网格的流动定位
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【NGINX】Windows配置
缺省安装nginx之后的配置 检查80端口占用 启动缺省配置之后的nginx 配置多端口站点 注册Server,server_name是配置的域名,proxy_pass是上图配置的代理地址 注意: 1 ...
- Bypass 360主机卫士SQL注入防御(多姿势)
0x00 前言 在服务器客户端领域,曾经出现过一款360主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影.从半年前的测试虚拟机里面,翻出了360主机卫士Apache版 ...
- thinkjs2.2中的定时任务
暂且先讨论定时任务的其中两种实现方法: 1.setInterval() setInterval()可按照指定的周期(毫秒数计)来调用函数或者计算表达式: setInterval()方法会不停的调用该函 ...
- codeforces水题100道 第十六题 Codeforces Round #164 (Div. 2) A. Games (brute force)
题目链接:http://www.codeforces.com/problemset/problem/268/A题意:足球比赛中如果主场球队的主场球衣和客队的客队球衣颜色一样,那么要求主队穿上他们的可对 ...
- No.4 PyQt学习(页面跳转)
先定义了两个MainWindow进行跳转,但发现这样的话,从第二个Window无法跳转会第一个.代码如下: # -*- coding: utf-8 -*- import sys from PyQt4. ...
- 微信小程序--消息推送配置Token令牌错误校验失败如何解决
微信开放第三方API接口, 申请地址: https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/inter ...