1. 程式人生 > >P4124 [CQOI2016]手機號碼

P4124 [CQOI2016]手機號碼

range adg ++ list 相同 () splay ns2 git

鏈接:https://www.luogu.org/problemnew/show/P4124

題目描述

人們選擇手機號碼時都希望號碼好記、吉利。比如號碼中含有幾位相鄰的相同數字、不含諧音不吉利的數字等。手機運營商在發行新號碼時也會考慮這些因素,從號段中選取含有某些特征的號碼單獨出售。為了便於前期規劃,運營商希望開發一個工具來自動統計號段中滿足特征的號碼數量。

工具需要檢測的號碼特征有兩個:號碼中要出現至少 33 個相鄰的相同數字;號碼中不能同時出現 88 和 44 。號碼必須同時包含兩個特征才滿足條件。滿足條件的號碼例如:13000988721、23333333333、14444101000。而不滿足條件的號碼例如:1015400080、10010012022。

手機號碼一定是 11 位數,前不含前導的 00 。工具接收兩個數 LL 和 RR ,自動統計出 [L,R][L,R] 區間內所有滿足條件的號碼數量。 LL 和 RR 也是 1111 位的手機號碼。

輸入輸出格式

輸入格式:

輸入文件內容只有一行,為空格分隔的 22 個正整數 L,RL,R 。

輸出格式:

輸出文件內容只有一行,為 11 個整數,表示滿足條件的手機號數量。

輸入輸出樣例

輸入樣例#1: 復制
12121284000 12121285550
輸出樣例#1: 復制
5

說明

樣例解釋:滿足條件的號碼: 12121285000、 12121285111、 12121285222、 12121285333、 12121285550。

數據範圍: 10^10LR<10^11

題解:數位dp, 還是挺容易yy出來的,但要去掉前導0的情況,<10^10是不合法的

技術分享圖片
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rt register
const int M = 2530;
ll dp[20][10][2][2][2][2];
int digit[20], cnt, tot, bg[M];

ll dfs(int dep, bool f, bool two, bool ok, int
t, bool a4, bool a8){ if(!dep) return (( !(a4 & a8) ) & ok); if(!f && dp[dep][t][two][ok][a4][a8] != -1) return dp[dep][t][two][ok][a4][a8]; rt int i = f ? digit[dep] : 9; ll tmp = 0; for(; i >= 0; i--){ if(dep==tot&&i==0) continue; bool ntwo, nok = ok; if(two && (t == i)) ntwo = 0, nok = 1; else if(i == t) ntwo = 1; else ntwo = 0; tmp += dfs(dep - 1, f & (i == digit[dep]), ntwo, nok, i, a4 | (i == 4), a8 | (i == 8)); } if(!f)dp[dep][t][two][ok][a4][a8] = tmp; return tmp; } ll get(ll a){ memset(dp, -1, sizeof(dp)); tot = 0; while(a){ digit[++tot] = a%10; a /= 10; } if(tot<11) return 0; ll ans = dfs(tot, 1, 0, 0, 0, 0, 0); return ans; } ll read(){ ll x = 0; ll f = 1; char c = getchar(); while(c<0||c>9){if(c==-)f=-1;c=getchar();} while(c<=9&&c>=0){x=x*10+c-0;c=getchar();} return x*f; } int main(){ ///freopen("1.in","r",stdin); //freopen("my.out","w",stdout); int T; memset(dp, -1, sizeof(dp)); ll L = read(), R = read(); ll ans2 = get(L - 1); ll ans1 = get(R); //cout<<ans1<<" "<<ans2; cout<<ans1-ans2<<endl; } //10000000000 10000012345
View Code

P4124 [CQOI2016]手機號碼