Loading

题解:CF204A Little Elephant and Interval

CF204A Little Elephant and Interval

题意

给定 \(l,r\) 求区间 \([l,r]\) 中数字首位和尾位相等的数字的个数。

数据范围:$1 \leq l \leq r \leq 10^{18} $(开 long long

思路

  • 首先想到通过暴力枚举区间内所有数,每次检测是否符合要求,但显然对于大范围的区间会超时。
  • 那么我们考虑找规律,直接对区间内的合法数统计比较麻烦,那我们不妨统计 \([1,r]\)\([1,l-1]\) 两个区间内合法数的个数,并做差。当右端点小于 \(10\) 时,那么个数一定为右端点的值。当右端点不小于 \(10\) 时,我们举几个例子:
 i   [1,i]总数  [10,i]总数
12  ->  10  ->  10-9=1
21  ->  10  ->  10-9=1
25  ->  11  ->  11-9=2
33  ->  12  ->  12-9=3
36  ->  12  ->  12-9=3

我们发现对于一个数 \(i\),在 \([10,i]\) 中,当 \(i\) 首位比尾位大,那么结果为 \(\lfloor \frac{i}{10} \rfloor - 1\),否则为 \(\lfloor \frac{i}{10} \rfloor\)。原因是个位每 \(10\) 一个循环,每个循环内一定有合法数,如 \(11,22,\dots,101,111,\dots,202,212\dots\),当尾位比首位小时,在该循环无法构成首尾相等,如 \(31 < 33\)

这是思路,更多详情请看代码。

代码

#include<bits/stdc++.h>
using namespace std;
long long get_first(long long n){ //取首位
	while(n>=10) n/=10;
	return n;
}
long long solve(long long n){
	if(n<10) return n;
	long long ans=n/10+9, last=n%10, first=get_first(n); //last为尾位,first为首位,答案别忘了+9
	if(first>last) ans--; //比较首尾,首比尾大-1
	return ans;
}
int main(){
	long long l, r;
	cin >> l >> r;
	cout << solve(r)-solve(l-1) << endl;
	return 0;
}

完结撒花!

posted @ 2024-07-15 14:59  Anins  阅读(34)  评论(0)    收藏  举报  来源