[蓝桥杯 2020 省 A1] 整数小拼接
题目描述
给定一个长度为
n
n
n 的数组
A
1
,
A
2
,
⋯
,
A
n
A_1,A_2,\cdots,A_n
A1,A2,⋯,An。你可以从中选出两个数
A
i
A_i
Ai 和
A
j
A_j
Aj(
i
≠
j
i\neq j
i=j),然后将
A
i
A_i
Ai 和
A
j
A_j
Aj 一前一后拼成一个新的整数。例如 12
和 345
可以拼成 12345
或 34512
。注意交换
A
i
A_i
Ai 和
A
j
A_j
Aj 的顺序总是被视为
2
2
2 种拼法,即便是
A
i
=
A
j
A_i=A_j
Ai=Aj 时。
请你计算有多少种拼法满足拼出的整数小于等于 K K K。
输入格式
第一行包含 2 2 2 个整数 n n n 和 K K K。
第二行包含 n n n 个整数 A 1 , A 2 , ⋯ , A n A_1,A_2,\cdots,A_n A1,A2,⋯,An。
输出格式
一个整数代表答案。
样例 #1
样例输入 #1
4 33
1 2 3 4
样例输出 #1
8
提示
对于 30 % 30\% 30% 的评测用例 1 ≤ n ≤ 1000 1\le n\le1000 1≤n≤1000, 1 ≤ k ≤ 1 0 8 1\le k\le10^8 1≤k≤108, 1 ≤ A i ≤ 1 0 4 1\le A_i\le10^4 1≤Ai≤104。
对于所有评测用例, 1 ≤ n ≤ 1 0 5 1\le n\le10^5 1≤n≤105, 1 ≤ k ≤ 1 0 10 1\le k\le10^{10} 1≤k≤1010, 1 ≤ A i ≤ 1 0 9 1\le A_i\le10^9 1≤Ai≤109。
蓝桥杯 2020 第一轮省赛 A 组 H 题。
解析
二分,对于左边部分序列肯定可以拼接,右边不可以拼接,二分找分割点
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 1e18
const int mod=1e9+7;
const int N=2e5+5;
int n,k,a[N];
int f(int a,int b){
return stoll(to_string(a)+to_string(b));
}
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
int ans=0;
for(int i=1;i<=n;i++){
int l=0,r=n,t=0;
while(l<=r){
int mid=l+r>>1;
if(f(a[i],a[mid])<=k) t=mid,l=mid+1;
else r=mid-1;
}
if(t>=i) ans+=t-1;
else ans+=t;
}
cout<<ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int tt=1;
// cin>>tt;
while(tt--) solve();
return 0;
}