题目链接
题目大意:要求每个奇数出现的次数为偶数,每个偶数出现的次数为奇数
状态压缩,一个长度为10的3进制数。
第i位上为0,表示i没出现过,为1表示i出现奇数次,为2表示i出现偶数次。
change函数进行状态转移
int change(int state,int pos){
int data=0;
if(state==0) data = 0;
else data = (state%w[pos+1])/w[pos];
if(data==0||data==1) state += w[pos];
if(data==2) state -= w[pos];
return state;
}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int len,dig[20];
ll w[20];
ll dp[20][59050];
int change(int state,int pos){
int data=0;
if(state==0) data = 0;
else data = (state%w[pos+1])/w[pos];
if(data==0||data==1) state += w[pos];
if(data==2) state -= w[pos];
return state;
}
bool check(int state){
int pos = 0;
while(state!=0){
int x;
x = state%3;
state /= 3;
if(x==1&&pos%2==1)return 0;
if(x==2&&pos%2==0)return 0;
pos ++;
}
return 1;
}
ll dfs(int pos,int state,bool zero,bool limit){
if(pos==0){
if(check(state)) return 1;
return 0;
}
if(!limit&&dp[pos][state]!=-1&&!zero) return dp[pos][state];
int i;
int up = limit?dig[pos]:9;
ll ans = 0;
for(i = 0;i <= up;i ++){
if(zero&&i==0) {
ans += dfs(pos-1,state,zero&&i==0,limit&&i==up);
continue;
}
int next = change(state,i);
ans += dfs(pos-1,next,zero&&i==0,limit&&i==up);
}
if(!limit&&!zero) dp[pos][state]= ans;
return ans;
}
ll solve(ll n){
len = 0;
while(n!=0){
dig[++len] = n%10;
n /= 10;
}
return dfs(len,0,1,1);
}
int main()
{
freopen("a.txt","r",stdin);
memset(dp,-1,sizeof(dp));
w[0] = 1;
for(int i = 1;i <= 10;i ++)
w[i] = w[i-1]*3;
ll l,r;
int T;
cin>>T;
while(T --){
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}