背景

这是一道比赛的题目。标题纯属虚构,仅供参考。其实我感觉做对了,只是没找到原题。而且题目也只是按照记忆。


题目

题目描述

定义函数 G(a,b)G(a,b) 表示拼接 aabb 。例如当 a=202,b=5a=202,b=5G(a,b)=G(202,5)=2025G(a,b) = G(202, 5) = 2025 。输入 nnmm ,求有多少对 a(1an)a(1≤a≤n)b(1bm)b(1≤b≤m) 能使 (a+1)(b+1)1=G(a,b)(a+1)*(b+1)-1=G(a,b) 成立。

输入格式

输入共一行,两个数 nnmm

输出格式

输出共一行,一个数表示有多少对 aabb

输入输出样例

输入 #1

1 12

输出 #1

1

输入 #2

56 1000

输出 #2

168

数据规模与约定

对于 100%100\% 的数据:

  • 1n,m2×1091≤n,m≤2×10^9

题解

这一看就知道不是模拟(1n,m2×1091≤n,m≤2×10^9)。但是先用模拟做,如果有什么发现呢?

直接循环 aabb 就好了。代码:

#include <iostream>
#define int long long
using namespace std;

int G(int a, int b)
{
	string s1 = to_string(a), s2 = to_string(b);
	string s3 = s1 + s2;
	return stoll(s3);
}

signed main()
{
	int n, m, ans = 0;
	cin >> n >> m;
	for (int a = 1; a <= n; a++)
	{
		for (int b = 1; b <= m; b++)
		{
			if ((a + 1) * (b + 1) - 1 == G(a, b))ans++;
		}
	}
	cout << ans;
	return 0;
}

直接看答案不能发现什么规律。只知道 168168565633 倍。把 aabb 输出看看。对于样例二,输出:

1 9
1 99
1 999
2 9
2 99
2 999
3 9
3 99
3 999
...
53 9
53 99
53 999
54 9
54 99
54 999
55 9
55 99
55 999
56 9
56 99
56 999

可以发现,循环的 aa 是一直成立的,只需要找到有多少个 bb 是成立的就好了。观察输出的 bb ,发现只有 999999999999 。如果继续往下,就会有 999999999999999999 等。因此,我设计了这样一个函数:

int f(int x)
{
	if (x < 9)return 0;
	if (x < 99)return 1;
	if (x < 999)return 2;
	if (x < 9999)return 3;
	if (x < 99999)return 4;
	if (x < 999999)return 5;
	if (x < 9999999)return 6;
	if (x < 99999999)return 7;
	if (x < 999999999)return 8;
	if (x < 9999999999)return 9;
}

这就能找出有多少个 bb 是成立的。答案就是: n×f(m)n × f(m) 。最后的代码:

#include <iostream>
#define int long long
using namespace std;

int f(int x)
{
	if (x < 9)return 0;
	if (x < 99)return 1;
	if (x < 999)return 2;
	if (x < 9999)return 3;
	if (x < 99999)return 4;
	if (x < 999999)return 5;
	if (x < 9999999)return 6;
	if (x < 99999999)return 7;
	if (x < 999999999)return 8;
	if (x < 9999999999)return 9;
}

signed main()
{
	int n, m;
	cin >> n >> m;
	cout << n * f(m);
	return 0;
}