CCUT应用OJ题解——重复数

题意

  • 来源:1134 - 重复数 | CCUTOJ
  • 题意:在等式 A + B = C A+B=C A+B=C 中,若 C > 10 C>10 C>10 C C C 中各数位相同,则定义 A , B A,B A,B 为重复数,其中 A ≤ B A\le B AB。求 [ X , Y ] [X,Y] [X,Y] 中存在几对重复数。
  • 数据范围: 1 ≤ X ≤ Y ≤ 1 0 6 1\le X\le Y\le 10^6 1XY106

题解

由于 A , B ≤ 1 0 6 A,B\le 10^6 A,B106,故 C ≤ 2 × 1 0 6 C\le 2\times 10^6 C2×106

手写出几个可能的 C C C C = 11 , 22 , … , 99 , 111 , 222 , … , 999 , … C=11,22,\dots,99,111,222,\dots,999,\dots C=11,22,,99,111,222,,999,,可发现 C C C 中每多一个位数, C C C 的数量 + 9 +9 +9。因此当 C C C 上界为 2 × 1 0 6 2\times 10^6 2×106 时, C C C 的数量不会超过 100 100 100。因此我们预处理出所有的 C C C,并反推出所有 ( A , B ) (A,B) (A,B)

我们将固定 A A A,将所有的 B B B 均替换为 A A A 的形式,则 B = C − A B=C-A B=CA A A A 的约束条件包括:
X ≤ A , B ≤ Y A ≤ B \begin{align} X\le A,B\le Y\\ A\le B \end{align} XA,BYAB
( 1 ) (1) (1) 式改写为 X ≤ A ≤ Y , X ≤ C − A ≤ Y X\le A\le Y, X\le C-A\le Y XAY,XCAY,故:
C − Y ≤ A ≤ C − X \begin{equation} C-Y\le A\le C-X \end{equation} CYACX
( 2 ) (2) (2) 式改写为:
A ≤ C 2 \begin{equation} A\le \frac{C}{2} \end{equation} A2C
整理可得:
{ X ≤ A ≤ C 2 C − Y ≤ A ≤ C − X \begin{cases} X & \le A \le \frac{C}{2}\\ C-Y & \le A \le C-X \end{cases} {XCYA2CACX
我们只需对上述不等式取交集,即可确定 A A A 的取值范围:
max ⁡ ( X , C − Y ) ≤ A ≤ min ⁡ ( C 2 , C − X ) \max(X,C-Y)\le A\le \min(\frac{C}{2},C-X) max(X,CY)Amin(2C,CX)
这一范围内每个元素均为A。记 l o w = max ⁡ ( X , C − Y ) , h i g h = min ⁡ ( C 2 , C − X ) low=\max(X,C-Y), high=\min(\frac{C}{2},C-X) low=max(X,CY),high=min(2C,CX)

  • h i g h < l o w high<low high<low,无解
  • 否则,答案即为 h i g h − l o w + 1 high-low+1 highlow+1
#include <bits/stdc++.h>
using namespace std;
using i64=long long;
const i64 MAX = 2000000;
vector<i64> c;
void init() {
	for (int k = 2; k <= 9; k++) {
		for (int d = 1; d <= 9; d++) {
			i64 temp = 1LL * (int)((pow(10, k) - 1) / 9) * d;
			if (temp > MAX) break;
			c.push_back(temp);
		}
	}
	sort(c.begin(), c.end());
}
int main() {
	ios::sync_with_stdio(0),cin.tie(0);
	init();
	i64 x, y;
	while (cin >> x >> y) {
		i64 ans = 0;
		for (auto i : c) {
			i64 low  = max(x, i - y);
			i64 high = min(y, min(1LL * i / 2, i - x));
			if (high >= low) {
				ans += (high - low + 1);
			}
		}
		cout << ans << "\n";
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值