P4124 [CQOI2016]手機號碼
阿新 • • 發佈:2018-08-15
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^10≤L≤R<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, intView Codet, 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
P4124 [CQOI2016]手機號碼