数
タイトル説明
300iqは、300の倍数である数字を愛しています。
ある日、彼は、文字列が数字で構成されました。彼は十進整数として考えたときに、文字列の多くの部分文字列は、300の倍数であるかを知りたいです。
先頭と末尾のゼロは許可されていることに注意してください(両方とも元の文字列と部分文字列にあなたが選んだ)と異なる場所に出現する同じ部分には、複数回カウントすることができます。
説明を入力します。
文字列からなる単一の行が「9」に文字「0」から成っていました。
出力説明:
十進整数として考えたときに300の倍数である部分文字列の数。
備考:
入力中の文字列を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 。 }
もちろん、この問題は、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 。 }