做这题的时候因为没有看清题目走了好多弯路,题目中要去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;
}