人們選擇手機號碼時都希望號碼好記、吉利。比如號碼中含有幾位相鄰的相同數字、不含諧音不吉利的數字等。手機運營商在發行新號碼時也會考慮這些因素,從號段中選取含有某些特徵的號碼單獨**。為了便於前期規劃,運營商希望開發乙個工具來自動統計號段中滿足特徵的號碼數量。
工具需要檢測的號碼特徵有兩個:號碼中要出現至少 3 個相鄰的相同數字;號碼中不能同時出現 8 和 4。號碼必須同時包含兩個特徵才滿足條件。滿足條件的號碼例如:13000988721、23333333333、14444101000。而不滿足條件的號碼例如:1015400080、10010012022。
手機號碼一定是 11 位數,前不含前導的 0。工具接收兩個數 l* 和 r*,自動統計出 [l,r]區間內所有滿足條件的號碼數量。l 和 r也是 11位的手機號碼。
輸入檔案內容只有一行,為空格分隔的 2 個正整數 l,r。
輸出檔案內容只有一行,為 1 個整數,表示滿足條件的手機號數量。
輸入
輸出12121284000 12121285550
樣例解釋:滿足條件的號碼: 12121285000、 12121285111、 12121285222、 12121285333、 12121285550。5
資料範圍:1010
\(\leq\)l\(\leq\)r<1011
一開始我以為這又是一道板子題,只不過狀態有點多,大概要開到6維
於是我就寫了下面的**交了上去
樣例過了,還不錯,於是我就信心滿滿地交了上去,結果發現wa,70分#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
ll f[13][13][13][3][3][3],num[30];
ll a,b;
ll aaaa=0;
ll asd(ll now,ll bef,ll beff,bool jud4,bool jud8,bool jud3,bool lim)
if(f[now][bef][beff][jud4][jud8][jud3]!=-1 && !lim)
ll mmax=9;
if(lim==1) mmax=num[now];
ll anss=0;
for(ll i=0;i<=mmax;i++)
if(!lim) f[now][bef][beff][jud4][jud8][jud3]=anss;
return anss;
}ll solve(ll xx)
return asd(cnt-1,0,0,0,0,0,1);
}int main()
一開始我認為是字首0的問題,但是一想,其實並沒有那麼簡單,為什麼呢
因為題目中給出的資料範圍是1010
\(\leq\)l\(\leq\)r<1011
也就是說,第一位並不會出現0的情況(我一開始是這麼想的)
即使出現了0,那麼你是把00012345679判成是**號碼還是不是呢,畢竟**號碼和數字不一樣
於是我就檢視了一下wa的資料,發現了乙個神奇的問題
wa資料:
wa的資料竟然都是以10000000000開始的,也就是符合要求的最小的數輸入:
10000000000 10002098555
答案1685496
使用者輸出
4821665153
輸入:10000000000 23456271996
答案:796184381
使用者輸出
5616164038
輸入:10000000000 53628881996
答案:2186241614
使用者輸出
7006221271
這會帶來什麼問題呢?
聰明的你應該已經想到了
我們差分是所傳的引數是solve(bb)-solve(aa-1)
也就是說,如果給出的資料是10000000000的話,我們傳到solve函式中會變成了9999999999,這出現什麼問題呢
這會導致字首0的增多
因為我的函式中傳了當前這一位前面的第一位以及前面的第二位
如果我們是按1010算的話12332112會被算成**號碼,而如果按9*109算的話上面的數就不會被算出**號碼
所以我們只要特判,把1010的結果提前處理就可以了
據說有很多題解過不了10000000000 10000000000這組資料#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
ll f[13][13][13][3][3][3],num[30];
ll a,b;
ll aaaa=0;
ll asd(ll now,ll bef,ll beff,bool jud4,bool jud8,bool jud3,bool lim)
if(f[now][bef][beff][jud4][jud8][jud3]!=-1 && !lim)
ll mmax=9;
if(lim==1) mmax=num[now];
ll anss=0;
for(ll i=0;i<=mmax;i++)
if(!lim) f[now][bef][beff][jud4][jud8][jud3]=anss;
return anss;
}ll solve(ll xx)
if(yy==9999999999) return 5899826978;
return asd(cnt-1,19,12,0,0,0,1);
}int main()
(應該輸出1)
洛谷P4170 CQOI2007 塗色
假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅 綠 藍 綠 紅色,用乙個長度為5的字串表示這個目標 rgbgr。每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,...
洛谷 P4170 CQOI2007 塗色
假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅 綠 藍 綠 紅色,用乙個長度為5的字串表示這個目標 rgbgr。每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,...
洛谷 P4170 CQOI2007 塗色
假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅 綠 藍 綠 紅色,用乙個長度為5的字串表示這個目標 rgbgr。每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,...