#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <time.h>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
long long dp[20][20][10][2][2][2];
int num[20];
int s[20];
//第 i 位,长度为 len,上一位是什么,前面是否递增过,前面是否递减过,当前是否符合回文串的性质,flag就是普通的前一位是否有限制,q是盘是否前导0
long long rec(int i,int pre,int up,int down,int flag,int q,int len,int ispa)
{
if(i<0)
return up&&down&&ispa;
if(dp[i][len][pre][up][down][ispa]!=-1&&!flag&&!q)
return dp[i][len][pre][up][down][ispa];
long long res=0;
int o=s[i];
for(int j=0;j<10;j++)
{
num[i]=j;
if(j>o&&flag)
break;
if(q)
res+=rec(i-1,j,0,0,j<o?0:flag,q&&j==0,len-(q&&j==0),ispa);
else if(j==pre)
{
if(ispa&&i<len/2)
res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);
else
res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,ispa);
}
else if(j>pre)
{
if(!down)
continue;
if(ispa&&i<len/2)
res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);
else
res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,ispa);
}
else if(j<pre)
{
if(up)
continue;
if(ispa&&i<len/2)
res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);
else
res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,ispa);
}
}
if(!flag&&!q)
dp[i][len][pre][up][down][ispa]=res;
return res;
}
long long cal(long long x)
{
int len=0;
while(x)
{
s[len++]=x%10;
x/=10;
}
return rec(len-1,0,0,0,1,1,len,1);
}
int main()
{
memset(dp,-1,sizeof(dp));
long long l,r;
int t;
scanf("%d",&t);
while(t--){
scanf("%lld%lld",&l,&r);
printf("%lld\n",cal(r)-cal(l-1));
}
return 0;
}
未检测,不能交题,但是应该是对的
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <time.h>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
int a[20];
int keep[20];
int dp[20][20][20][2][2][2];
ll dfs(int len,int pos,int pre,int up,int down,int limit,int flag0,int judge)
{
if(pos<0)
return up&&down&&judge;
if(!flag0&&!limit&&dp[len][pos][pre][up][down][judge]!=-1)
return dp[len][pos][pre][up][down][judge];
ll sum=0;
int tmp=a[pos];
for(int i=0;i<=9;i++)
{
keep[pos]=i;
if(limit&&i>tmp)
break;
if(flag0)
sum+=dfs(len-(flag0&&i==0),pos-1,i,0,0,limit&&i==tmp,flag0&&i==0,judge);
else if(i==pre)
{
if(judge&&pos<len/2)
sum+=dfs(len,pos-1,i,up,down,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);
else
sum+=dfs(len,pos-1,i,up,down,limit&&i==tmp,flag0&&i==0,judge);
}
else if(i>pre)
{
if(!down)
continue;
if(judge&&pos<len/2)
sum+=dfs(len,pos-1,i,1,down,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);
else
sum+=dfs(len,pos-1,i,1,down,limit&&i==tmp,flag0&&i==0,judge);
}
else if(i<pre)
{
if(up)
continue;
if(judge&&pos<len/2)
sum+=dfs(len,pos-1,i,up,1,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);
else
sum+=dfs(len,pos-1,i,up,1,limit&&i==tmp,flag0&&i==0,judge);
}
}
if(!flag0&&!limit)
dp[len][pos][pre][up][down][judge]=sum;
return sum;
}
ll solve(ll x)
{
if(x<=100)
return 0;
int pos=0;
while(x)
{
a[pos++]=x%10;
x/=10;
}
return dfs(pos,pos-1,0,0,0,1,1,1);
}
int main()
{
memset(dp,-1,sizeof(dp));
ll l,r;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}
912

被折叠的 条评论
为什么被折叠?



