(一)
虽说代码较长,但非常好理解,还是最优解(公开的就两个)。
考虑对每个数单独算贡献,循环枚举与它进行运算的数的长度,然后确定那个数的位置即可,再乘以出现的数位对应的贡献,如出现在倒数第二位就乘 \(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;
}
标签:int,题解,代码,long,100010,CF1195D2
From: https://www.cnblogs.com/Jh763878/p/18098703