1026: [Scoi2009]windy number time limit:1 Sec Memory limit:162 MB
submit:7195 solved:3238
[Submit] [Status] [Discuss] Description
Windy defines a windy number. A positive integer that does not contain a leading 0 and the difference of at least 2 of the adjacent two digits is called the windy number. Windy want to know,
What is the total number of windy between A and B, including A and b?
Input
Contains two integers, A B.
Output
An integer
Sample Input"Input Sample One"
1 10
"Input Sample Two"
theSample Output"Output Example One"
9
"Output Example II"
-HINT
"Data size and conventions"
100% data, meet 1 <= A <= B <= 2000000000.
Source
Sol:
Re-learn digital DP
Set $f[i][j]$ to indicate that the current number has an I bit, and the number of scenarios where I bit is J
So obviously the transfer is $f[i][j]=f[i-1][k] (|j-k| \ge 2) $
If this number has a $len$ bit
When we count the answers, we first count all the numbers in the first bit of the $len$ that are smaller and not 0.
We then enumerate all the numbers from the $len-1$ bit to the $1$ bit and then calculate
And then this time the first one fixed US enumerate the rest of the digits if it's illegal to quit immediately.
/*To the End of the Galaxy*/#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<iomanip>#include<bitset>#include<stack>#include<map>#include<Set>#include<cmath>#include<complex>#defineDebug (x) cerr<< #x << "=" <<x<<endl#defineINF 0x7f7f7f7f#defineLlinf 0X7FFFFFFFFFFFLL#defineP (x, Y) (((x-1) *c) +y)using namespaceStd;typedef pair<int,int>Pii;typedefLong LongLl;inlineintinit () {intnow=0, ju=1;CharCBOOLflag=false; while(1) {C=GetChar (); if(c=='-') ju=-1; Else if(c>='0'&&c<='9') { now=now*Ten+c-'0'; Flag=true; } Else if(flag)returnnow*Ju; }}inlineLong LongLlinit () {Long Longnow=0, ju=1;CharCBOOLflag=false; while(1) {C=GetChar (); if(c=='-') ju=-1; Else if(c>='0'&&c<='9') { now=now*Ten+c-'0'; Flag=true; } Else if(flag)returnnow*Ju; }}ll f[ -][Ten];voidCalc () { for(intI=0; i<=9; i++) {f[1][i]=1; } for(intI=2; i<= -; i++) { for(intj=0; j<=9; j + +) { for(intk=0; k<=9; k++) { if(ABS (J-K) >=2) {F[i][j]+=f[i-1][k]; } } } }}intnum[ -];intCnt=0; ll solve (ll x) {intCnt=0; ll ans=0; while(x) {num[++cnt]=x%Ten; X/=Ten; } for(intI=1; i<cnt;i++) { for(intj=1; j<=9; j + +) {ans+=F[i][j]; } } for(intI=1; i<num[cnt];i++) {ans+=F[cnt][i]; } for(inti=cnt-1; i>=1; i--) { for(intj=0; j<num[i];j++) { if(ABS (num[i+1]-J) >=2) ans+=F[i][j]; } if(ABS (num[i]-num[i+1]) <2) Break; } returnans;} #ifdef UNIX#defineLLD "%lld"#else #defineLLD "%i64d"#endifintMain () {ll A, B; Calc (); A=llinit (); b=Llinit (); printf (Lld,solve (b+1)-solve (a)); return 0;}
View Code
"BZOJ1026" Windy number