hdu5898 odd-even number

題意:問(l,r)內,連續的奇數有偶數位,連續的偶數有奇數位,有多少這樣的數字

題解:數位dp,注意前導0就可以

LL dp[20][20][2][2];
int wei[20];

///weishu表示處理到了第幾位,pre代表前一位是奇數還是偶數,len表示前面奇數或偶數連續的長度,zero表示是否有前導0
LL dfs(int weishu, int pre, int len, int zero, int fool){
    if(weishu < 0) return (pre&1) != (len&1);
    if(!fool && dp[weishu][len][pre][zero]!=-1)
        return dp[weishu][len][pre][zero];
    int temp=fool ? wei[weishu] : 9;
    LL ans=0;
    for(int i=0;i<=temp;i++){
        if(zero==0){
            if(i==0){
                ans+=dfs(weishu-1, 0, 0, 0, fool && i==temp);
            }
            else {
                ans+=dfs(weishu-1, i&1, 1, 1, fool && i==temp);
            }
        }
        else {
            if(i&1){
                if(pre&1){
                    ans+=dfs(weishu-1, i&1, len+1, 1, fool && i==temp);
                }
                else {
                    if(len&1)
                        ans+=dfs(weishu-1, i&1, 1, 1, fool && i==temp);
                }
            }
            else {
                if(pre&1){
                    if(!(len&1))
                        ans+=dfs(weishu-1, i&1, 1, 1, fool && i==temp);
                }
                else {
                    ans+=dfs(weishu-1, i&1, len+1, 1, fool && i==temp);
                }
            }
        }
    }
    if(!fool){
        dp[weishu][len][pre][zero]=ans;
    }
    return ans;
}

LL solve(LL x){
    int len=0;
    while(x){
        wei[len++]=x%10;
        x/=10;
    }
    return dfs(len-1,0,0,0,1);
}

LL l,r;

int main(){
    int t;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    for(int ii=1;ii<=t;ii++){
        cin>>l>>r;
        printf("Case #%d: %lld\n",ii,solve(r) - solve(l-1));
    }
    return 0;
}


發佈了37 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章