zoukankan      html  css  js  c++  java
  • HDU 5898 odd-even number 数位DP

    odd-even number

    题目连接:

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5898

    Description

    For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).

    Input

    First line a t,then t cases.every line contains two integers L and R.

    Output

    Print the output for each case on one line in the format as shown below.

    Sample Input

    2
    1 100
    110 220

    Sample Output

    Case #1: 29
    Case #2: 36

    Hint

    题意:

    一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的。问[L , R]的好数个数。

    题解

    直接数位DP就好了。。。。

    因为数据范围很小,所以怎么写都可以

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 20 + 15;
    
    long long dp[maxn][2][2][2][2];
    
    char str[maxn] ;
    
    inline void up( long long & x , long long v ){ x += v;}
    
    long long solve( long long x ){
        if( x == 0 ) return 1;
        memset( dp  , 0 , sizeof( dp ) );
        int len = 0 ;
        while( x > 0 ){
            str[ ++ len ] = x % 10 + '0';
            x /= 10;
        }
        str[len + 1] = 0;
        reverse( str + 1 , str + len + 1 );
        //cout << "check num is " << str + 1 << endl;
        dp[0][1][0][0][1] = 1;
        for(int i = 0 ; i < len ; ++ i)
            for(int lead = 0 ; lead < 2 ; ++ lead)
                for(int f = 0 ; f < 2 ; ++ f)
                    for(int pre = 0 ; pre < 2 ; ++ pre)
                        for(int cur = 0 ; cur < 2 ; ++ cur)
                            if( dp[i][lead][f][pre][cur] ){
                                int ed = f ? 9 : str[i + 1] - '0';
                                for(int add = 0 ; add <= ed ; ++ add){
                                    int newf = f | (add < ed);
                                    if( lead == 1 ){
                                        if( add == 0 ) up( dp[i + 1][lead][newf][pre][cur] , dp[i][lead][f][pre][cur] );
                                        else up( dp[i + 1][0][newf][add & 1][1] , dp[i][lead][f][pre][cur] );
                                    }else{
                                        if( ( add & 1 ) == pre ) up( dp[i + 1][lead][newf][add & 1][cur ^ 1] , dp[i][lead][f][pre][cur] );
                                        else{
                                            if( pre == cur ) continue;
                                            up( dp[i + 1][lead][newf][add & 1][1] , dp[i][lead][f][pre][cur] );
                                        }
                                    }
                                }
                            }
        long long ans = 0;
        for(int lead = 0 ; lead < 2 ; ++ lead ) for(int f = 0 ; f < 2 ; ++ f) for(int pre = 0 ; pre < 2 ; ++ pre) up( ans , dp[len][lead][f][pre][pre ^ 1] );
        return ans;
    }
    
    int main( int argc , char * argv[] ){
        int T , cas = 0;
        scanf( "%d" , & T );
        while( T -- ){
            long long L , R ;
            scanf( "%I64d%I64d" , & L , & R );
            printf( "Case #%d: %I64d
    " , ++ cas , solve( R ) - solve( L - 1 ) );
        }
        return 0;
    }
  • 相关阅读:
    MySQl数据约束练习
    MySQL查询实例
    网络通信协议简介(TCP与UDP)
    数据类型转换
    C++编译过的C代码为什么要用extern C
    hashtable
    以RB-tree为底层机制的几个关联式容器
    红黑树(RB-Tree)
    slist
    deque
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5891010.html
Copyright © 2011-2022 走看看