输入格式
共一行,包含两个整数 X 和 Y。
输出格式
输出奶牛们在旅途中发出叫声的次数。
数据范围
100≤X≤Y≤10^16
输入样例:
110 133
输出样例:
13
样例解释
110∼133 之间的所有数字中,有趣数字为:110,112,113,114,115,116,117,118,119,121,122,131,133。
枚举
注意!!! 数据范围是最大16位数,必须long long才能hold住
思路:
- 错误的: 暴力枚举x~y范围的,一定超时!
- 那么反向思维,有趣的数肯定没这么多,那么枚举所有有趣数,判断是否在范围即可
- 如何构造有趣数: 最简单的方法就是从全相同的数改变一个即可
- 注意: 前导0的数不成立,排除即可。
具体写法见注释
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
int main(){
long long x,y;
cin>>x>>y;
int ans = 0;
// 遍历3~16位数的“全相同数” 构造有趣数
for(int i = 3; i <= 17; ++i)
{
// jjj...j,由i个j构成的全相同数
for(int j = 0; j < 10; ++j)
{
// 构造数字的字符串形式
string str(i, '0'+j);
// 将全j数中的某一位替换为k
for(int k = 0; k < 10; ++k)
{
if(k == j) continue; // 相同非替换
// 替换第u位的数
for(int u = 0; u < i; ++u)
{
str[u] = '0' + k;
long long num = atoll(str.c_str());
// 在范围内且无前导零
if(str[0] != '0' && x <= num && num <= y) ans++;
// 恢复现场
str[u] = ('0'+j);
}
}
}
}
cout<<ans<<endl;
return 0;
}