CF1195D2的题解

(一)

虽说代码较长,但非常好理解,还是最优解(公开的就两个)。

考虑对每个数单独算贡献,循环枚举与它进行运算的数的长度,然后确定那个数的位置即可,再乘以出现的数位对应的贡献,如出现在倒数第二位就乘 \(10\)

难度应该不到绿。

(二)

AC 代码。

#include<bits/stdc++.h>
#define int long long//记得开 long long
using namespace std;
const int md=998244353;
int n,sum[21],mx,ans,a[100010],siz[100010];
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%lld",&x);a[i]=x;
		while(x)siz[i]++,x/=10;
		sum[siz[i]]++;//统计数的位数
		mx=max(mx,siz[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=mx;j++){
			if(!sum[j])continue;
			int p1=siz[i],p2=j,d=1,s=0,x=a[i];
			bool flag=0;//flag 表示填的是当前数,还是进行运算的另一个数
			while(p1&&p2){
				if(!flag)s=(s+(x%10)*d)%md,p1--,x/=10;
				else p2--;
				flag^=1;
				d=d*10%md;
			}
			while(x){
				s=(s+(x%10)*d)%md;
				x/=10;
				d=d*10%md;
			}
			ans=(ans+sum[j]*s)%md;
		}
		for(int j=1;j<=mx;j++){
			if(!sum[j])continue;
			int p1=siz[i],p2=j,d=1,s=0,x=a[i];
			bool flag=1;
			while(p1&&p2){
				if(!flag)s=(s+(x%10)*d)%md,p1--,x/=10;
				else p2--;
				flag^=1;
				d=d*10%md;
			}
			while(x){
				s=(s+(x%10)*d)%md;
				x/=10;
				d=d*10%md;
			}
			ans=(ans+sum[j]*s)%md;
		}
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2024-03-27 12:23  Jerry_heng  阅读(10)  评论(0)    收藏  举报