E. Count The Blocks(找数学规律)
\(\color{Red}{先说一下自己的歪解(找规律)}\)
\(n=1是答案是10\)
\(n=2时答案是180\)
\(n=3时模拟一下,很容易发现答案是2610\ \ 180\ \ 10\)
\(然后我们大胆推测,n增加后,只有答案第一位发生变化,其余照搬n-1的答案\)
\(然后发现n=3有1000个三位数,每个数有3个数字加起来是1000*3个数字\)
\(刚才得出n=3时连续块长3有10种(0000,1111,...,9999),也就用掉了10*3个数字\)
\(n=3时连续块长2有180种,也就用掉了180*2个数字\)
\(所以易得连续块长1有3000-30-360=2610\)
\(于是我们可以开始递推。\)
\(递推方法是:当前总数字-当前所用数字=块长1的数字\)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2*1e5+9; const ll mod=998244353; ll dp[maxn],fac[maxn]; int main() { int n; cin>>n; fac[1]=10; for(int i=2;i<=n;i++) fac[i]=fac[i-1]*10%mod; dp[n]=10; ll sumn=20,tt=10;//初始化n=2时 for(int i=n-1,j=2;i>=1;i--,j++)//递推n=j时块长1的数量 { ll he=fac[j]*j%mod;//n=j时的总数字 dp[i]=(he-sumn+mod)%mod;//计算n=j时块长1的数字 sumn+=dp[i]*2+tt;//因为是2 3 4 5递增 tt+=dp[i]; sumn%=mod,tt%=mod; } for(int i=1;i<=n;i++) cout<<dp[i]<<" "; }
相关推荐
xceman 2020-10-13
算法与数学之美 2020-10-07
Anscor 2020-10-05
liwg0 2020-09-08
数学爱好者 2020-08-31
thermodynamicB 2020-08-11
夕加加 2020-07-20
willowwgx 2020-07-18
kuoying 2020-07-16
Anscor 2020-07-14
starletkiss 2020-07-08
kingzone 2020-06-27
xceman 2020-06-27
算法与数学之美 2020-06-21
kuoying 2020-06-21
秒懂数学 2020-06-17