[JZOJ3316] non palindrome number

Keywords: PHP

description

If a string is read from the back to the front to the back, we call it palindrome string. When a number does not contain a subpalindrome number with a length greater than 1, it is called a non palindrome number. For example, 16276 is a non palindrome number, but 17276 is not, because it contains the palindrome number 727.

Your task is to calculate the total number of non palindrome numbers in a given range.

analysis

  • The most recommended digit in your life (DP \), ask to split it into two parts.

  • I f \ (f[i][j][k][0/1] \) is set, it means the number of legal schemes with the number of \ (I \), the number of \ (I \) being \ (j \), the number of \ (i-1 \) being \ (K \), and whether it is just top bound.

  • Transfer naturally means \ (f[i][j][k][0]+=f[i-1][k][num][0/1] \). Note that the transfer with or without the upper bound is different.

  • We can see that it's hard to make such a leader \ (0 \), so we can change it.

  • Set \ (g[i][j][k] \) to indicate the scheme number of \ (I \), the number of \ (I \) to \ (j \), and the number of \ (i-1 \) to \ (K \), and transfer separately.

  • That is to say, if the number is not enough, it must be smaller than the original number, regardless of the upper bound. It means that these numbers have a leading \ (0 \), which has been calculated.

  • That is to say, the first place of the custom \ (f \) and \ (g \) is not \ (0 \) start \ (DP \), and finally add \ (f \) and \ (g[1.. digit-1] \) together.

code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define ll long long
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i)

using namespace std;

ll f[20][10][10][2];
ll g[20][10][10];
ll a[20];
ll l,r,mx;

inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline ll get(ll x)
{
    if (x<10)return x;
    mx=floor(log10(x)+1);
    fd(i,mx,1)a[i]=x%10,x/=10;
    memset(f,0,sizeof(f));
    memset(g,0,sizeof(g));
    f[1][a[1]][0][1]=1;
    fo(i,1,a[1]-1)f[1][i][0][0]=1;
    fo(i,1,9)g[1][i][0]=1;
    fo(i,2,mx)
    fo(j,0,9)//Number i
    fo(k,0,9)//Digit i-1
    {
        if (j==k)continue;
        fo(num,0,9)//Digit i-2
        {
            if (i>2 && num==j)continue;
            g[i][j][k]+=g[i-1][k][num];
            if (j==a[i] && k==a[i-1])
            {
                f[i][j][k][0]+=f[i-1][k][num][0],
                f[i][j][k][1]+=f[i-1][k][num][1];
            }
            else
            {
                if (k<a[i-1] || (k==a[i-1] && j<a[i]))
                    f[i][j][k][0]+=f[i-1][k][num][0]+f[i-1][k][num][1];
                else f[i][j][k][0]+=f[i-1][k][num][0];
            }
        }
    }
    ll ans=0;
    fo(i,1,mx-1)fo(j,0,9)fo(k,0,9)ans+=g[i][j][k];
    fo(i,0,9)fo(j,0,9)ans+=f[mx][i][j][0]+f[mx][i][j][1];
    return ans;
}
int main()
{
    l=read(),r=read();
    printf("%lld\n",get(r)-get(l-1));
    return 0;
}

Posted by cillosis on Fri, 01 Nov 2019 12:17:45 -0700