B - ATCoder

GitHub跳转原题关系图返回列表

扫描字符串,维护当前连续 ACGT 字符的长度,遇非法字符归零,取过程中最大值。

OJ: atcoder

题目 ID: abc122_b

难度:入门

标签:haskell

日期: 2026-07-10 15:33

题意

求字符串中最长的、仅由 A C G T 构成的连续子串的长度。

思路

扫描字符串,维护当前连续 ACGT 长度,遇非 ACGT 归零,过程中取最大值。

代码

haskell
{-
 Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 rainboy的学习导航网站: https://idx.roj.ac.cn
 create_at: 2026-07-10 15:37
 update_at: 2026-07-10 15:37
-}
main = do
    s <- getLine
    print $ maximum $ scanl (\cur c -> if c `elem` "ACGT" then cur + 1 else 0) 0 s

另一种写法,更接近 DP / C++ 思维:

haskell
isACGT c = c `elem` "ACGT"

solve = go 0 0
  where
    go cur ans [] = ans
    go cur ans (c:cs)
        | isACGT c  = go (cur+1) (max ans (cur+1)) cs
        | otherwise = go 0 ans cs

main = do
    s <- getLine
    print $ solve s

还有用 tails + takeWhile 的写法:

haskell
{-
 Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 rainboy的学习导航网站: https://idx.roj.ac.cn
 create_at: 2026-07-10 15:44
 update_at: 2026-07-10 15:44
-}
import Data.List (tails)

main = do
    s <- getLine
    print $ maximum $ 0 : [ length (takeWhile (`elem` "ACGT") t) | t <- tails s ]

复杂度

时间复杂度 O(S)O(|S|),空间复杂度 O(1)O(1)

总结

scanl 版本简洁,递归版本直观。核心都是"遇 ACGT 累加,否则归零"。