【计数】【CF-1327E】Count The Blocks

【题意】

  给定一个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 }
View Code
原文地址:https://www.cnblogs.com/Osea/p/12602972.html