【题意】
给定一个n,然后按0~10^n - 1 ,比如n=3,000~999,然后如果相同的数字会变成一个块,如001,就有1个块长度为2的,1个块长度为1的。这个题目就是让我们求出在长度为n的所有数字中,每一个长度块对应的个数。
【题解】
通过题意,我们首先不能逐个遍历的方法来做,我们应该找规律。
我们主要分两个部分来计算,两端和中间。
两端:2*10*9*10^(n-i-2)
“10”,指的是在端点的位置上0~10
“9”,指的是相邻的时候应该取不等于端点位置的值。
“10^(n-i-2)”,指的是剩余位置随意。
“2”,端点位置为2.
中间:(n-i-1)9*10*9*10^(n-i-2)
"n-i-1",指的是中间的所有位置
"9*9",指的是夹住中间的两个相邻位置
"10",指的是当前位置任意取
"10^(n-i-2)",指的是剩下来的位置随意
最后我们发现,为了更好地计算,我们其实可以把i=1,n随之变化即可。
n=4,i=2,-> n = 3 , i = 1
【具体代码】
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 typedef long long ll ; 8 const ll mod = 998244353 ; 9 const int N = 2e6 + 10; 10 11 ll qpow( ll a , ll b ){ 12 ll ans = 1 ; 13 while( b ){ 14 if( b & 1 ){ 15 ans = ans * a % mod ; 16 } 17 b >>= 1 ; 18 a = a * a % mod ; 19 } 20 return ans ; 21 } 22 23 ll f[N] ; 24 int main() 25 { 26 int n ; 27 scanf("%d",&n); 28 f[1] = 10 ; 29 for( int i = 1 ; i <= n - 1 ; i++ ){ 30 int No = n - i + 1 ; 31 f[No] = ( 18 * qpow( 10 , No - 1 ) % mod ) ; 32 33 if( No >= 2 ){ 34 f[No] = ( f[No] + (No-2) * 81 * qpow(10,No-2) % mod ) % mod ; 35 } 36 } 37 38 for( int i = n ; i >= 1 ; i-- ){ 39 printf("%lld%c",f[i],i==1?' ':' '); 40 } 41 return 0; 42 }