题目链接:[蓝桥杯 2020 省 A1] 整数小拼接 - 洛谷
思路:
首先,要对数组a排序,并用len数组记录拼接后,若这个数放在后面,那么另一个数要乘的倍率。
然后,若a与e拼接的数(ae)比k小,那么ab、ac、ad都应该比k小(他们符合单调递增规律),因此只需找到a在前时,与最后一个与a结合小于k的数,这里可以用二分法提高效率。
注意点:若找到最后一个与a结合小于k的数e,此时要注意减去aa这种情况,因为要选两个整数拼接,不可以选取同一个数。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100005;
typedef long long ll;
ll len[N];
ll a[N];
ll n,k;
ll num;
ll l,r,mid;
ll ans;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;++i) cin>>a[i];
sort(a+1,a+n+1);
num=k;
len[0]=1;
while(num)
{
len[0]*=10;
num/=10;
}
for(int i=1;i<=n;++i)
{
num=a[i];
len[i]=1;
while(num)
{
len[i]*=10;
num/=10;
}
}
for(int i=1;i<=n;++i)
{
l=0,r=n;
while(l<r)
{
mid= l+r+1 >> 1;
if(a[i]*len[mid]+a[mid]<k&&a[i]*len[mid]+a[mid]>0) l=mid;
else r=mid-1;
}
if(l>=i) l--;
ans+=l;
//cout<<i<<" "<<l<<endl;
}
cout<<ans<<endl;
return 0;
}