• hdu 3967 Zero's Number


    题意:将一个数划分成两部分,如果过分出来的两部分相加能被k整除,则这种划分时可行的,题目要我们求的是一段区间内的数有多少种可行的划分方法(PS:一个数可以有多种划分方法,如333 3有两种分别是33|3 , 3|33)

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

    dp[i][j][k][l]表示处理到第i位,划分位置为j,除数为k,余数为l的,划分方法数。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 #define ll __int64
     6 ll dp[18][18][22][22],md[19]={0,1};
     7 void init()
     8 {
     9     for(int i=2;i<19;i++)
    10     md[i]=10*md[i-1];
    11     memset(dp,0,sizeof(dp));
    12     for(int k=1;k<21;k++)
    13         for(int l=0;l<k;l++)
    14             for(int j=0;j<10;j++)
    15                 if(j%k==l)
    16                     dp[1][1][k][l]++;
    17     for(int i=2;i<18;i++){
    18         for(int j=1;j<=i;j++){
    19             for(int k=1;k<21;k++){
    20                 for(int l=0;l<k;l++){
    21                     for(int j1=0;j1<10;j1++){
    22                         if(i!=j){
    23                             ll tmp=(j1*md[i-j])%k;
    24                             dp[i][j][k][l]+=dp[i-1][j][k][(l+k-tmp)%k];
    25                         }
    26                         else{
    27                             ll tmp=(j1*md[i])%k;
    28                             dp[i][i][k][l]+=dp[i-1][i-1][k][(l+k-tmp)%k];
    29                         }
    30                     }
    31                 }
    32             }
    33         }
    34     }
    35 }
    36 ll solve(ll x,ll k)
    37 {
    38     ll dig[20],cnt=0,ans=0,tx=x;
    39     while(x){
    40         dig[++cnt]=x%10;
    41         x/=10;
    42     }
    43     if(cnt>2){
    44         for(int i=1;i<cnt-1;i++)
    45         ans+=dp[cnt-1][i][k][0];
    46         for(int i=cnt-2;i>0;i--)
    47         ans-=dp[i][i][k][0];
    48     }
    49     
    50     for(int i=1;i<dig[cnt];i++){
    51         for(int j=1;j<cnt;j++){
    52             ll tmp=(i*md[cnt-j])%k;
    53             ans+=dp[cnt-1][j][k][(k-tmp)%k];
    54         }
    55         
    56     }
    57     for(int i=cnt-1;i>1;i--){
    58         for(int j=0;j<dig[i];j++){
    59             ll cntt=cnt-1,tmp2=0,tmp1=dig[cnt];
    60             while(cntt>i){
    61                 tmp2=10*tmp2+dig[cntt];
    62                 cntt--;
    63             }
    64             for(int kk=cnt-1;kk>=i;kk--){
    65                 ll tmp3=(tmp1)%k;
    66                 ll tmp4=(tmp2*md[i+1])%k;
    67                 ll tmp5=(j*md[i])%k;
    68                 ans+=dp[i-1][i-1][k][(k-tmp3-tmp4-tmp5+2*k)%k];
    69                 tmp1=tmp1*10+dig[kk];
    70                 tmp2=tmp2-dig[kk]*md[kk-i];
    71             }
    72             tmp1=tmp1-dig[i]+j;
    73             for(int kk=i-1;kk>0;kk--){
    74                 ll tmp3=(tmp1*md[i-kk])%k;
    75                 ans+=dp[i-1][kk][k][(k-tmp3)%k];
    76             }
    77         }
    78     }
    79     for(int i=0;i<dig[1];i++){
    80         ll su1=tx-dig[cnt]*md[cnt]-tx%10,su2=tx/md[cnt];
    81         for(int j=cnt-1;j>0;j--){
    82             if((su1+su2+i)%k==0)
    83                 ans++;
    84             su2=10*su2+dig[j];
    85             su1=su1-dig[j]*md[j];
    86         }
    87     }
    88     return ans;
    89 }
    90 int main()
    91 {
    92     init();
    93     ll l,r,k,cnt=1;
    94     while(~scanf("%I64d%I64d%I64d",&l,&r,&k)){
    95         printf("%I64d
    ",solve(r+1,k)-solve(l,k));
    96     }
    97     return 0;
    98 }
    AC Code
  • 相关阅读:
    SpannableString
    Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区别
    Java 之 File
    android 获取配置文件 相对路径
    Canvas
    Java Set List Map
    Comparable与Comparator区别
    HashMap HashTable ConcurrentHashMap
    centos7 mongodb 3.4 yum 安装
    对于JAVA程序优化的一些想法,读书有感.治疗强迫症良药
  • 原文地址:https://www.cnblogs.com/kim888168/p/3276993.html
Copyright © 2020-2023  润新知