XiaoHuang's Space
XiaoHuang's Space
XiaoHuang
May the force be with you.
「AT1175」ニコニコ文字列
Posted: Dec 14, 2019
This article was last modified days ago. The content of this post may be outdated!

Portal

Portal1: Atcoder

Portal2: Luogu

Description

$0$ から $9$ の数字から成る文字列 $S$ が与えられます。

ある文字列 $X$ について、$X=$”$25$” または $X=$”$2525$” または $X=$”$252525$” …… というふうに “$25$” を何回か繰り返した文字列になっているとき、$X$ はニコニコ文字列であるといいます。 たとえば “$25$” や “$25252525$” はニコニコ文字列ですが、”$123$” や “$225$” はニコニコ文字列ではありません。

あなたの仕事は、文字列 $S$ について、ニコニコ文字列となるような連続した部分文字列の取り出し方が何通りあるかを答えることです。 文字列として同じであっても、取り出し位置が異なっていれば別々に数えます。

Input

入力は以下の形式で標準入力から与えられる。

$S$

$1$ 行目には、文字列 $S$ が与えられる。Sの長さは $1$ 以上 $100,000$ 以下である。また、$S$ の各文字は $0$ から $9$ の数字のみから成る。

Output

$1$ 行目には、文字列 $S$ からニコニコ文字列となるような連続した部分文字列を取り出す方法が何通りあるかを出力せよ。

行末の改行を忘れると不正解と判定されるので注意すること。

Sample Input1

2525

Sample Output1

3

Sample Input2

1251251252525

Sample Output2

8

Sample Input3

25225

Sample Output3

2

Sample Input4

252252252252252252

Sample Output4

6

Sample Input5

20061212

Sample Output5

0

Sample Explain1

$S=$”$2525$”のケースです。部分文字列が “$25$” となる取り出し方が 2 通り、”$2525$” となる取り出し方が $1$ 通りあるので合計 $3$ 通りを出力します。

Hint

この問題には部分点が設定されています。

$N \le 2000$ を満たすデータセット $1$ にすべて正解すると、$30$ 点が得られます。 追加制約のないデータセット $2$ にすべて正解すると、上記のデータセットに加えてさらに $70$ 点が得られ、全体で $100$ 点が得られます。

Description in Chinese

给出由$0 - 9$数字构成的字符串$S$。

对某个字符串$X$来说,如果$X=$”$25$”或$X=$”$2525$”或$X=$”$252525$”$\cdots \cdots$,$X$像这样由”$25$”重复多次组成,那么就称$X$为niconico字符串。例如”$25$”或”$252525$”就是niconico字符串,而”$123$”或”$225$”不是niconico字符串。

你的任务是,对于字符串$S$,请回答出$S$中有多少个子串为niconico字符串。即使子串相同,但是如果子串在原串中位置不同,也要分别计入总数中。

Solution

我们可以先把连续的25都替换从一个字符,如a,然后我们找连续的25,每一段25都可以用组合数计算出niconico的数量。然后累加就可以了。

坑:注意要开long long

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>

using namespace std;

typedef long long LL;
string st;
int main() {
    cin >> st;
    string b = "";
    for (int i = 0; i < st.length() - 1; i++)
        if (st[i] == '2' && st[i + 1] == '5') b = b + 'a', i++; else b = b + st[i];//将所有的"25"转化为'a'
    b = '1' + b + '1';//防止溢出,添加边界
    LL l = -1, r = 0, ans = 0;//必须要long long
    for (int i = 1; i < b.length() - 1; i++) {
        if (b[i] == 'a' && b[i - 1] != 'a' && l == -1) l = i;
        if (b[i] == 'a' && b[i + 1] != 'a') {
            r = i;
            ans += (r - l + 1) * (r - l + 2) / 2;//计数连续一段的价值
            l = -1;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
Article License: CC BY-NC-ND 4.0
Article Author: XiaoHuang
  1. 1. Portal
  2. 2. Description
  3. 3. Input
  4. 4. Output
  5. 5. Sample Input1
  6. 6. Sample Output1
  7. 7. Sample Input2
  8. 8. Sample Output2
  9. 9. Sample Input3
  10. 10. Sample Output3
  11. 11. Sample Input4
  12. 12. Sample Output4
  13. 13. Sample Input5
  14. 14. Sample Output5
  15. 15. Sample Explain1
  16. 16. Hint
  17. 17. Description in Chinese
  18. 18. Solution
  19. 19. Code
Newer Post
「数学」三角函数公式以及部分证明
Older Post
『模板』快速读入 & 输出模板
Buy me a beer?
-->
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×