ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[2019.10.25]训练赛T3 手机号码

2019-10-25 21:03:48  阅读:272  来源: 互联网

标签:25 号码 满足条件 LL 手机号码 T3 训练赛 MAXM include


手机号码

题目描述

人们选择手机号码时都希望号码好记、吉利。比如号码中含有几位相邻的相同数字、不含谐音不吉利的数字等。手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号码单独出售。为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码数量。
工具需要检测的号码特征有两个:号码中要出现至少3个相邻的相同数字;号码中不能同时出现4和8 。号码必须同时包含两个特征才满足条件。满足条件的号码例如:13000988721、23333333333、14444101000。而不满足条件的号码例如:1015400080、10010012022。手机号码一定是11位数,且不含前导0 。工具接收两个数 l 和 r , 自动统计出区间内所有满足条件的号码数量。l 和 r 也是11位的手机号码。
·······························

输入格式

输入文件内容只有一行,为空格分隔的两个正整数 L, R

输出格式

输出文件内容只有一行,为一个整数,表示满足条件的手机号数量。

分析:

很显然, 使用数位dp, 详见注释

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXM 15
#define LL long long
#define Int register int
using namespace std;
LL num[MAXM];
LL dp[MAXM][MAXM][MAXM][2][2][2][2];
inline LL Max(LL x,LL y)
{
    return x > y ? x : y;
}
inline LL Min(LL x,LL y)
{
    return x < y ? x : y;
}
inline void read(LL &x)
{
 x = 0;
 LL f = 1;
 char s = getchar();
 while (s < '0' || s > '9')
 {
     if (s == '-')
         f = -1;
     s = getchar();
 }
 while (s >= '0' && s <= '9')
 {
     x = (x << 3) + (x << 1) + (s ^ 48);
     s = getchar();
 }
 x *= f;
}
LL Num_dp(int p,int a,int b,bool l,bool s,bool c4,bool c8)
{
 /*
 p : 当前数位
 a : p + 1位的数
 b : p + 2位的数, 如果为前导0则为 -1
 l : 判断连续
 s : 判断是否前面已经严格小于, 方便填数
 c4、c8 : 判断 4 和 8 
 */
    if (c4 && c8)
        return 0;
    if (p <= 0)
        return l;
    if (~ dp[p][a][b][l][s][c4][c8])
        return  dp[p][a][b][l][s][c4][c8];
    LL Sum = 0, Limit = ! s ? num[p] : 9;
    for (Int i = 0; i <= Limit; ++ i)
        Sum += Num_dp(p - 1, i, a, l || (i == a && a == b), s || (i < Limit), c4 || (i == 4), c8 || (i == 8));
    return dp[p][a][b][l][s][c4][c8] = Sum;
}
LL solve(LL x)
{
    if (x < 10000000000ll)
        return 0;
    memset(dp, -1, sizeof dp);
    int len = 0;
    while ( x )
    {
        num[++ len] = x % 10;
        x /= 10;
    } 
    LL Ans = 0;
    for (Int i = 1; i <= num[len]; ++ i)
        Ans += Num_dp(10, i, 0, 0, i < num[len], i == 4, i == 8);
    return Ans;
}
int main()
{
    LL L, R;
    read( L ); read( R );
    printf("%lld", solve( R ) - solve(L - 1));
    return 0;
}

标签:25,号码,满足条件,LL,手机号码,T3,训练赛,MAXM,include
来源: https://blog.csdn.net/ICEEBBING/article/details/102749304

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有