E. Final Countdown(1500)
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int t=1;cin>>t;
while(t--){
int n;cin>>n;
string s;cin>>s;
reverse(s.begin(),s.end());
//个位,大位
vector<int>a(n+1);
for(int i=n-1;i>=0;i--){
a[i]=a[i+1]+(s[i]-'0');//个位是好多数的个位,累加
}string res;
int c=0;
for(int i=0;i<n;i++){
c+=a[i];//先加最高位
res+=(char)(c%10+'0');//个位当前位
c/=10;//进位
}
//882
//88
//8
//个位出现1次
//十位两次(十的二次方+十的一次方),百位3次( 十的三次方+十的二次方+十的一次方
//我们直接算 x/1 + x/10 + x/100… 会超级大,存不下。
//d0 只出现在:x/1
//d1 出现在:x/1、x/10
//d2 出现在:x/1、x/10、x/100
res+=(char)(c+'0');
while(res.back()=='0'){
res.pop_back();
}reverse(res.begin(),res.end());
cout<<res<<'\n';
}
return 0;
}
解析
1.见注释
2.按位
如果从右往左给指示器编号(从 0 开始),那么第 i 位指示器恰好会翻转 ⌊s/10i⌋ 次。
为了计算这个和,我们把数字 s 拆成单独的数位,再累加每一位的贡献。
对 42:
- 个位(i=0):42 / 1 = 42 次
- 十位(i=1):42 / 10 = 4 次
总和:42 + 4 = 46