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