Luogu P4124 [CQOI2016]手机号码 题解

Describe

题目链接

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

Solution

数位dp
注意细节

Code

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int a[15],m,f[15][10][10][2][2][2][2][2];
inline int DFS(int x,int las,int lasqr,int has,int is4,int is8,int lim,int st){
    if(is4&&is8) return 0;
    if(x==0) return has;
    if(~f[x][las][lasqr][has][is4][is8][lim][st]) return f[x][las][lasqr][has][is4][is8][lim][st];
    int Max=lim?a[x]:9,res=0;
    for(int i=0;i<=Max;i++)
        if(st==1) res+=DFS(x-1,i,las,has,is4||(i==4),is8||(i==8),lim&&(i==Max),st&&(i==0));
        else res+=DFS(x-1,i,las,has||(las==lasqr&&las==i),is4||(i==4),is8||(i==8),lim&&(i==Max),st&&(i==0));
    return f[x][las][lasqr][has][is4][is8][lim][st]=res;
}
inline int solve(int n){
    m=0;memset(f,-1,sizeof(f));
    while(n){
        a[++m]=n%10;
        n/=10;
    }
    return DFS(m,-1,-1,0,0,0,1,1);
}
int L,R;
signed main(){
    scanf("%lld%lld",&L,&R);
    printf("%lld\n",solve(R)-solve(L-1));
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇