题目链接
这道题的数据范围要暴力很容易,但是如果数据范围变大,比如10^100那么数位dp无疑是最好的,简单的复习一下数位DP。数位DP讲解
#define inf 0x3f3f3f3f
#define ll long long
#define vec vector<int>
//#define P pair<int,string>
#define MAX 105
int L, R, dp[10][10];//dp[i][j]:i位数,最高位为j时有多少2
int cal(string n) {
int res = 0, l = n.size();
for (int i = 1; i < n[0] - '0'; i++)//加上最高位比它小的
res += dp[l][i];
for (int i = 1; i < l; i++)
for (int j = 1; j < 10; j++)
res += dp[i][j];//加上位数比他少的,最高位不能为0
//最高位一致,低位比她小
for (int i = l - 1; i >= 1; i--) {
for (int j = 0; j < n[l - i] - '0'; j++) {//最高位固定,后面的每一位取小于关系
res += dp[i][j];
if (n[0] == '2')res += pow(10, i - 1);
}
}
return res;
}
int main() {
memset(dp, 0, sizeof(dp)); dp[1][2] = 1;
for (int i = 2; i < 10; i++)
for (int j = 0; j < 10; j++) {
if (j == 2)dp[i][j] = pow(10, i - 1);//20的话有 20-29 10个加上上一位的
for (int k = 0; k < 10; k++)
dp[i][j] += dp[i - 1][k];
}
cin >> L >> R;
string r = to_string(R + 1), l = to_string(L);
cout << cal(r) - cal(l) << endl;//传入的是R+1
}