做这题的时候因为没有看清题目走了好多弯路
,题目中要去i<j,所以不会出现抽取相同下标的数。也是因为这个要求所以不能对数组直接进行排序,会将数组顺序打乱导致错误的。
但要求数位差如果有序的话最好的办法是求得大于等于10-a,100-a,1000-a的个数,然后相加。但本题不能直接排序。
然后可以想到使用整体二分递归的方式,将右半边排序,从遍历左半边去计算右半边有多少符合的数。这样由于递归栈的性质,从小的区间开始计算所以就算排序也不会影响后续的结果。因为左半边的顺序对结果没影响。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e8+10;
int n;
int a[maxn];
ll solve(int l, int r) {
// cout<<l<<" "<<r<<endl;
if (l==r) return 0;
int mid = (l+r)/2;
ll ans = 0;
ans += solve(l, mid)+solve(mid+1, r);
// cout<<l<<" "<<r<<endl;
sort(a+mid+1, a+r+1);
for (int i=l;i<=mid;i++) {
for (int j=10;j<=1e9;j = j*10)
{
if (a[i]<j) {
int posl = a+r+1-lower_bound(a+mid+1, a+r+1, j-a[i]);
ans+=posl;
}
}
}
return ans;
}
int main() {
scanf("%d", &n);
for (int i=0;i<n;i++) {
scanf("%d", a+i);
}
ll cnt = solve(0, n-1);
cout<<cnt<<endl;
return 0;
}

京公网安备 11010502036488号