zoukankan      html  css  js  c++  java
  • NEUQ OJ 2004:追梦之人 (计数数位dp)

    2004: 追梦之人

    描述

    题目描述:

    为了纪念追梦人,粉丝们创造了一种新的数——“追梦数”。追梦数要满足以下两个条件:
    1、数字中不能出现“7”
    2、不能被7整除。
    比如:777和4396就不是追梦数,而666是追梦数。现在他们想知道,1到N中有多少个追梦数。

    输入:

    多组数据。
    第一行给出一个正整数T。T为数据组数。
    接下来T行,每行包括一个正整数N。
    (1 leq T leq 10001T1000
    (1 leq N leq 10^{18}1N1018)

    输出:

    对于每组数据,在单独的一行中输出一个整数表示1到N中有多少个追梦数。

    样例输入
    4
    10
    14
    17
    100
    样例输出
    9
    12
    14
    70

    当初石乐志要维护三个东西,后来发觉数位只要维护两个东西就好了。
    我们的答案是n-被7整除的数-不被7整除但包含7的数。
    被7整除的数n/7即可求出。
    后面这个写个数位dp即可。
    dpi[k]表示长度为i,膜7的余数为j,是否含7的情况为k(k为0表示不含,为1表示含)的数的数量,考虑当前的第i位为x,之前的i-1位组成的数膜7的余数为y,那么dpi+=dpi-1。如果x不是7,那么k应该是0转移到0,1转移到1;如果x是7,那么都转移到k=1。剩下的就是裸的数位dp了。
    注意边界。

     1 #include<bits/stdc++.h>
     2 #define clr(x) memset(x,0,sizeof(x))
     3 #define clr_1(x) memset(x,-1,sizeof(x))
     4 #define mod 7
     5 #define LL long long
     6 #define INF 0x3f3f3f3f
     7 #define mp make_pair
     8 #define pb push_back
     9 #define mp make_pair
    10 #define fi first
    11 #define se second
    12 using namespace std;
    13 const int N=1e5+10;
    14 LL all[30][10][2],num[30];
    15 void init()
    16 {
    17     all[0][0][0]=1;
    18     num[1]=1;
    19     for(int i=2;i<=18;i++)
    20         num[i]=(num[i-1]*10)%mod;
    21     for(int i=1;i<=18;i++)
    22         for(int j=0;j<=9;j++)
    23             for(int k=0;k<7;k++)
    24                 if(j!=7)
    25                 {
    26                     all[i][(int)(j*num[i]%mod+k)%mod][1]+=all[i-1][k][1];
    27                     all[i][(int)(j*num[i]%mod+k)%mod][0]+=all[i-1][k][0];
    28                 }
    29                 else
    30                      all[i][(int)(j*num[i]%mod+k)%mod][1]+=all[i-1][k][1]+all[i-1][k][0];
    31 }
    32 LL n,m,k;
    33 LL ans;
    34 int a[N],t,now;
    35 bool flag;
    36 int T;
    37 int main()
    38 {
    39     init();
    40     scanf("%d",&T);
    41     while(T--)
    42     {
    43         scanf("%lld",&n);
    44         ans=n-n/7;
    45         m=0;
    46         n++;
    47         while(n)
    48         {
    49             a[++m]=n%10;
    50             n/=10;
    51         }
    52         now=0;
    53         flag=0;
    54         for(int i=m;i>=1;i--)
    55         {
    56             for(int j=0;j<a[i];j++)
    57             {
    58                 for(int k=0;k<mod;k++)
    59                     if((j*num[i]%mod+k+now)%mod!=0)
    60                     {
    61                         ans-=all[i-1][k][1];
    62                         if(flag || j==mod)
    63                             ans-=all[i-1][k][0];
    64                     }
    65             }
    66             now=(now+a[i]*num[i])%mod;
    67             if(a[i]==mod)
    68                 flag=1;
    69         }
    70         printf("%lld
    ",ans);
    71     }
    72 }
    View Code
  • 相关阅读:
    streamreader
    python编码问题总结
    linux rz上传文件及出错解决方案
    使用linux远程登录另一台linux
    利用Django实现RESTful API(一)
    windows下搭建vue开发环境
    windows下python虚拟环境virtualenv安装和使用
    SonarQube的安装、配置与使用
    windows下安装Mysql(图文详解)
    静态代码分析工具sonarqube+sonar-runner的安装配置及使用
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9034305.html
Copyright © 2011-2022 走看看