题解:SP10649 MYQ10 - Mirror Number
Mirror Number是只有数字
定义 Mirror Number 是一个自然数
n ,满足:设n=a_0+10a_1+10^2a_2+\cdots+10^ma_m,\ m\in\N,a_i\in\{0,1,2,3,4,5,6,7,8,9\}\ (\forall 0\le i\le m\land i\in\N), 那么对于任意
0\le i\le m\land i\in\N ,有a_i\in\{0,1,8\} ,且a_i=a_{m-i} 。
设 dp[i] 是位数为 i 的 Mirror Number 的数量(没有前导零,所以这里
接下来考虑计算答案,定义一个函数 get(x) 表示区间 [0,x] 内 Mirror Number 的数量,如果
还需要一个函数 check(x),检查
当输入 get(b)-get(a)+check(a),由于题目范围中 Mirror Number 的自由度不超过 get 返回值不超过 long long 返回。
时间复杂度是
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T, nxt[9] = {1, 8, 0, 0, 0, 0, 0, 0, 10};
string a, b;
ll dp[45];
bool check(string x){
for(int i=0;i*2<=x.length();i++){
if (x[i] != x[x.length()-i-1] || (x[i] != '0' && x[i] != '1' && x[i] != '8'))
return 0;
}
return 1;
}
ll pow3(ll y){
return y?pow3(y-1)*3:1;
}
ll get(string x){
if (x.length() == 1 && x[0] == '0') return 1;
// [0, x]
ll len = x.length(), ans = 0;
// 小于len位
for (int i=0;i<len;i++) ans += dp[i];
// 等于len位
string s;
for(int i=0;i*2+1<=len;i++){
int num = x[i] - '0', c = i==0;
while(c < num){
// 已用长度:i+1 => ans += 3^(len-2*(i+1) )
if (2*i+1 == len) ans++;
else {
int re = len - 2*(i+1);
ans += pow3(re/2 + re%2);
}
c = nxt[c];
}
if (c == num) s += x[i];
else return ans;
}
string t = s.substr(0, s.length() - len%2);
reverse(t.begin(), t.end());
s += t;
ans += (s <= x);
return ans;
}
int main(){
cin>>T;
dp[0] = 1;
for(int i=1;i<=44;i++){
dp[i] = 2 * pow3(i/2 + i%2 - 1);
}
while(T--){
cin>>a>>b;
cout << get(b) - get(a) + check(a) << endl;
}
}