大致题意:定义h(x , y)为 x + y 的进位次数 ,求给定(i , j)范围内所有h(i , j)的和
分析:一一枚举所有每组数字进位复杂度是O(n ^ 2),考虑二分找到符合题意的位置,对于每次进位,我们只处理一次,ai <= 109, 取9次模即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N];
ll b[N];
int main()
{
int n , k;
while (scanf("%d" , &n) != EOF)
{
memset(a , 0 , sizeof a);
memset(b , 0 , sizeof b);
//vector<ll> ans;
b[0] = -1; //不用到b[0]就进行赋初值防止排序排错
for (int i = 1; i <= n; i ++ ) cin >> a[i];
ll j = 1;
ll res = 0;
for (int k = 1; k <= 9; k ++ )
{
j *= 10;
for (int i = 1; i <= n; i ++ ) b[i] = a[i] % j; // 每次取最后一位进行统计,但当比如999 % 1000 = 999 因为之前我们已经统计两次了,加上1大于等于1000,也算一次仍符合题意
sort(b + 1 , b + n + 1);
for (int i = 1; i <= n; i ++ )
{
ll l = i , r = n;
while (l < r)
{
ll mid = l + r >> 1;
if (b[i] + b[mid] >= j) r = mid;
else l = mid + 1;
}
if (l == i && b[l] + b[i] >= j) res += n - l;
else if (i < l && b[i] + b[l] >= j) res += n - l + 1;
//cout << l << " ";
}
//cout << endl;
}
//ans.clear();
cout << res << endl;
}
return 0;
}