2019頭の牛オフより学校4つのK番号(DPまたは接頭辞と)

 

タイトル説明 

 

300iqは、300の倍数である数字を愛しています。
ある日、彼は、文字列が数字で構成されました。彼は十進整数として考えたときに、文字列の多くの部分文字列は、300の倍数であるかを知りたいです。
先頭と末尾のゼロは許可されていることに注意してください(両方とも元の文字列と部分文字列にあなたが選んだ)と異なる場所に出現する同じ部分には、複数回カウントすることができます。

説明を入力します。

文字列からなる単一の行が「9」に文字「0」から成っていました。

出力説明:

十進整数として考えたときに300の倍数である部分文字列の数。
例1

エントリー

コピー
600

輸出

コピー
4

説明

「600」、「0」、「0」、「00」は、300の倍数である(それが2回出現しているため、「0」は二度カウントされることに注意してください)
例2

エントリー

コピー
123000321013200987000789

輸出

コピー
55

備考:

入力中の文字列をs、なりましょう  よ| 1 \当量| \当量10 ^ 5 1 | S | 1 0 5。

文字列に、私はどのように多くのサブ割り切れる文字列300を尋ね、先行ゼロが含まれています。

DPは、[I]は[j]は位置の前に全ての位置に形成され%300 == jの数の数を示し、i及び

これは、現在の状態にプッシュすることができる[I + 1] [(J * 10の+ S [I + 1] - '0')%300]

したがって、状態遷移方程式DP [I] [(J * 10の+ S [I] - '0')%300] + = DP [I - 1]〜[J] ..なお、初期値毎のDP [I] [ S [i]は - '0'] = 1。

<ビット/ STDC ++ H>の#include
 の#defineデバッグ(X)COUT << "[" << #X << ":" <<(X)<< "]" << ENDL
 の#define PII対<整数、整数>
 の#define CLR(B)のmemset((A)、B、はsizeof(A))
 の#define担当者(I、B)(iは= int型、iがBを<; I ++の)のため
 の#define PB一back
 の#define MPがmake_pair
 の#define LL長い長
 の#define ULL符号なしLL用
 の#define LS I << 1個
 の#define RS(I << 1)+ 1
 の#define INT(T)INT T。scanf関数( "%のD"、&T)使用して名前空間STDを、const int型 MAXN = 1E5 + 10 
DP LL [MAXN] [ 310

 

 ];
チャーS [MAXN]。

INT メイン(){
     しながら(〜のscanf(" %sは"、+ S 1 )){
         int型 LEN = STRLEN(S + 1 )。
        CLR(DP、0 );
        以下のためにint型 i = 1 ; iは= LEN <; ++ I){
             int型 TMP = S [I] - ' 0 ' 
            DP [I] [TMP] = 1 INT J = 0 ; J < 300 ; ++ j)は
                DP [I] [(J * 10 + TMP)%300 ] + = DP [I - 1 ] [J]。
        } 
        LL ANS = 0 以下のためにint型 i = 1 ; iは= LEN <; ++ I)
            ANS + = DP [I] [ 0 ]。
        coutの << ANS << てendl; 
    } 
    戻り 0 
}
コードの表示(DP)

 

もちろん、この問題は、2つの0上記== 0 3%の終わりに、明らかに300%== 0は、二つの条件を必要とする、プレフィックスを作るとすることができる、現在の位置と3%== 0、1、2の前の接頭語を記録することが可能です数は、その後に対応する番号を追加します

<ビット/ STDC ++ H>の#include
 の#defineデバッグ(X)COUT << "[" << #X << ":" <<(X)<< "]" << ENDL
 の#define PII対<整数、整数>
 の#define CLR(B)のmemset((A)、B、はsizeof(A))
 の#define担当者(I、B)(iは= int型、iがBを<; I ++の)のため
 の#define PB一back
 の#define MPがmake_pair
 の#define LL長い長
 の#define ULL符号なしLL用
 の#define LS I << 1個
 の#define RS(I << 1)+ 1
 の#define INT(T)INT T。scanf関数( "%のD"、&T)使用して名前空間STDを、const int型 MAXN = 1E5 + 10 チャーS [MAXN]。

 
 
 
 int型の合計[MAXN]。
int型の融点[MAXN * 10 ]。
 
INT メイン(){
     ながら(〜のscanf(" %sの"、+ S 1 )){ 
        CLR(MP、0 );
        INT SZ = STRLEN(S + 1 )。
        LL ANS = 0 以下のためにint型 = Iを1 ; I <= SZ; ++ I){ 
            和[I] =和[I - 1 ] + S [I] - ' 0 ' 
            和[I]%= 3;
            もし(S [I] == ' 0 ')++ ANS。
        } 
        のためにint型 I = 1 ; I + 1 <= SZ; ++ I){
             もし、(S [I] == ' 0 ' && S [I + 1 ] == ' 0 ' ){
                 ++ ANS。
//                 のprintf( "===>%のD、" MP [和[I - 1])。デバッグ(SUM [I - 1])。
                ANS + =融点[和[I - 1 ]。
                もし(合計[I - 1 ]%3!=0) - ANS。
            } 
//             デバッグ(ANS)。
            ++ 融点[合計[I]]; 
        } 
//         デバッグ(ANS)。
        coutの<< ANS << てendl; 
    } 
    戻り 0 
}
コードの表示(接頭辞)

 

おすすめ

転載: www.cnblogs.com/rookie-acmer/p/11258415.html