Problem:
IOIOI

問題

整数 n (1 ≤ n) に対し, n + 1 個の I と n 個の O を I から始めて交互に並べてできる文字列を Pn とする.ここで I と O はそれぞれ英大文字のアイとオーである.

P1

IOI

P2

IOIOI

P3

IOIOIOI

.

.

.

Pn

IOIOIO ... OI (O が n 個)

図 1-1 本問で考える文字列 Pn

整数 n と, I と O のみからなる文字列 s が与えられた時, s の中に Pn が何ヶ所含まれているかを出力するプログラムを作成せよ.

例

n が 1, s が OOIOIOIOIIOII の場合, P1 は IOI であり,下図 1-2 に示した 4ヶ所に含まれている.よって,出力は 4 である.

OOIOIOIOIIOII

OOIOIOIOIIOII

OOIOIOIOIIOII

OOIOIOIOIIOII

図 1-2 n が 1, s が OOIOIOIOIIOII の場合の例

n が 2, s が OOIOIOIOIIOII の場合, P2 は IOIOI であり,下図 1-3 に示した 2ヶ所に含まれている.よって,出力は 2 である.

OOIOIOIOIIOII

OOIOIOIOIIOII

図 1-3 n が 2, s が OOIOIOIOIIOII の場合の例

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

1 行目には整数 n (1 ≤ n ≤ 1000000) が書かれている.

2 行目には整数 m (1 ≤ m ≤ 1000000) が書かれている. m は s の文字数を表す.

3 行目には文字列 s が書かれている. s は I と O のみからなる.

全ての採点用データで, 2n + 1 ≤ m である.採点用データのうち, 配点の 50% 分については, n ≤ 100, m ≤ 10000 を満たす.

n が 0 のとき入力の終了を示す. データセットの数は 10 を超えない．

出力

データセットごとに,文字列 s に文字列 Pn が何ヶ所含まれるかを表す 1 つの整数を1 行に出力する. s に Pn が含まれていない場合は,整数として 0 を出力せよ.

入出力例

入力例

1
13
OOIOIOIOIIOII
2
13
OOIOIOIOIIOII
0

出力例

4
2

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative ((<$>))
import Control.Monad (replicateM, unless)

import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B

import Data.List (unfoldr)

main :: IO ()
main = do
  n <- readLn
  unless (n == 0) $ do
    getLine
    solve n <$> B.getLine >>= print
    main

solve :: Int -> ByteString -> Int
solve n = sum . map f . unfoldr ioi
  where f p = max 0 (p - n + 1)

ioi :: ByteString -> Maybe (Int, ByteString)
ioi bs = f 0 (B.drop 1 bs1)
  where (_, bs1) = B.break (== 'I') bs
        f ct s | B.null s = Nothing
               | B.take 2 s == oi = f (ct+1) (B.drop 2 s)
               | otherwise = Just (ct, s)
        oi = B.pack "OI"