题解:P11201 [JOIG 2024 Open] たくさんの数字 / Many Digits

除了搬题人之外的首 A,来纪念一下。

Solution P11201

Idea

我们先对 bb 数组排序,然后枚举 aa 数组。

不难发现:对于 aia_i,假如最后写出的数有 kk 位,则一定有 10k1aibj<10kai10^{k-1}-a_i\le b_j < 10^k-a_i

不难发现对于每一个 kk 对应的都是一个连续区间,于是可以二分。

具体实现起来,可以用 lower_bound 快速解决。

讲一下下面代码里的 lposnow 为什么可行:你会发现对于 k1k2=1k_1-k_2=1 的情况,两个要求分别是 10k21aibj<10k2ai10^{k_2-1}-a_i \le b_j < 10^{k_2}-a_i10k11aibj<10k1ai10^{k_1-1}-a_i \le b_j < 10^{k_1}-a_i。代入 k11=k2k_1-1=k_2 可得第一个式子是 10k12aibj<10k11ai10^{k_1-2}-a_i \le b_j < 10^{k_1-1}-a_i。两个式子一综合,这个显然就可行了。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=150005;
int n,a[N],b[N];
const int mi10[10]={0,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
long long ans;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)scanf("%d",&b[i]);
	sort(b+1,b+n+1);
	for(int i=1,lpos,now;i<=n;i++){
		lpos=n+1;
		for(int j=9;j>=0;j--){
			now=lower_bound(b+1,b+n+1,mi10[j]-a[i])-b;
			ans=ans+1ll*(lpos-now)*(j+1);
			lpos=now;
		}
	}
	printf("%lld",ans);
	return 0;
}
posted @   Weslie_qwq  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示