UVa11361

来源:互联网 发布:高斯算法如何确定项数 编辑:程序博客网 时间:2024/06/06 03:05

题目链接

简介:
a~b中能被n整除且数字根也能被n整除的数的个数

分析:
一眼数位dp
于是我就开始设计状态:f[i][j][p][q][0/1],表示第i位,填的数字是j,余数为p,数字根余数为q,卡不卡边界

这是我看到了k的范围
完了,开不下啊怎么办

然而,实际上

k最大值不超过90

因为2^31只有10位,即使都填9,得到的数字根也不超过90
(差点被歪国人骗了)

tip

认真分析数据的范围

题目给出的不一定准确
注意a==1的情况

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;ll f[11][10][100][100][2];ll n,m,k;int a[11],b[11];void cl(ll n,int *a){    int tt=0;    while (n)    {        a[++tt]=n%10;        n/=10;    }    for (int i=1;i<=tt/2;i++) swap(a[i],a[tt-i+1]);    a[0]=tt;}ll doit(int *a){    memset(f,0,sizeof(f));    int i,j,p,q,l,c;    for (i=0;i<=a[1];i++) f[1][i][i%k][i%k][i==a[1]]=1;    for (i=1;i<a[0];i++)        for (j=0;j<=9;j++)            for (p=0;p<k;p++)                for (q=0;q<k;q++)                    for (l=0;l<=1;l++)                    if (f[i][j][p][q][l])                    {                        int tt=9;                        if (l) tt=a[i+1];                        for (c=0;c<=tt;c++)                        {                            int p1=(p*10+c)%k;                //number                             int q1=(q+c)%k;                   //root of number                            f[i+1][c][p1][q1][c==a[i+1]&&l]+=f[i][j][p][q][l];                        }                    }    ll ans=0;    for (i=0;i<=9;i++)        for (j=0;j<=1;j++)            ans+=f[a[0]][i][0][0][j];    return ans;}int main(){    int T;    scanf("%d",&T);    while (T--)    {        scanf("%lld%lld%lld",&n,&m,&k);        if (k>90)        {            printf("0\n");            continue;        }        n--;        cl(n,a); cl(m,b);        if (n==0) a[0]++;        printf("%lld\n",doit(b)-doit(a));    }       return 0;}
原创粉丝点击