반딧불이 n마리가 한 줄로 앉아 있다.
줄의 상태는 길이 n인 문자열로 나타내며, O(영어 대문자 오)는 불이 켜진 반딧불이, .(마침표)는 불이 꺼진 반딧불이다.
1초가 지날 때마다 모든 반딧불이가 지금의 상태를 보고 한꺼번에 바뀐다.
지금 켜져 있는 반딧불이는 꺼진다.
지금 꺼져 있는 반딧불이는 바로 옆 이웃 가운데 지금 켜진 것이 딱 하나일 때만 켜진다.
켜진 이웃이 없거나 양옆 이웃이 둘 다 켜져 있으면 꺼진 채로 있는다.
바로 옆 이웃은 왼쪽 한 마리와 오른쪽 한 마리이고, 줄의 양 끝에 있는 반딧불이는 이웃이 하나뿐이다(줄의 처음과 끝은 서로 이웃이 아니다).
t초가 지난 뒤의 줄의 상태와, 1초 뒤부터 t초 뒤까지 각 순간에 켜져 있던 반딧불이 수를 모두 더한 값을 구하라.
예제의 줄은 1초 뒤 O....O., 2초 뒤 .O..O.O, 3초 뒤 O.OO...가 된다.
켜진 수는 차례로 2, 3, 3이라서 합은 8이다.
입력
첫 줄에 n과 t(1 ≤ n ≤ 200, 1 ≤ t ≤ 200)가 빈칸 하나로 띄워 주어지고, 둘째 줄에 처음 상태를 나타내는 길이 n인 문자열이 주어진다. 문자열은 O와 .으로만 되어 있다
출력
첫 줄에 t초 뒤의 줄의 상태(길이 n인 문자열), 둘째 줄에 켜져 있던 수의 합
예시 1 · stdin
7 3
.OO.O..
stdout
O.OO...
8
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
모두가 '지금'을 보고 한꺼번에 바뀌므로, 다음 상태는 지금 상태와 다른 배열에 적어야 해요. 새 배열을 만드는 방법이 언어마다 달라요. Python은 [0] * n, JS·TS는 new Array(n).fill(0), Java·C#은 new int[n], C++은 vector<int> next(n, 0), 크레이콘은 새목록(n, 0)이에요. C는 배열 두 개를 두고 memcpy로 옮겨요(C 배열은 =로 옮길 수 없어요). 함정 하나: nxt = cur는 복사가 아니에요. Python 리스트, JS 배열, Java·C# 배열, 크레이콘 목록에서 =는 같은 배열에 이름을 하나 더 붙일 뿐이라서, 다음 상태를 적는 순간 지금 상태가 바뀌고 오른쪽 반딧불이는 이미 바뀐 왼쪽 이웃을 보게 돼요. 예시의 답이 .O.....와 4로 나와요. C++의 vector만은 cur = next가 내용을 통째로 복사해요. 함정 둘: 줄의 끝에서는 이웃이 하나뿐이에요. i > 0인지 묻지 않고 cur[i - 1]을 읽으면 Python은 cur[-1]을 맨 끝 칸으로 읽어서 줄의 처음과 끝이 이웃이 돼요. 예시의 답이 ..OO...와 7로 나와요. 같은 코드가 Java에서는 ArrayIndexOutOfBoundsException, C#에서는 IndexOutOfRangeException으로 멈추고, 크레이콘도 없는 자리라고 알리며 멈춰요. JS는 undefined를 줘서 더하면 NaN이 되고, C와 C++은 무슨 일이 생길지 정해져 있지 않아요. 함정 셋: '딱 하나'를 '하나 이상'으로 읽으면 양옆이 모두 켜진 반딧불이까지 켜져요. 예시의 답이 O..O.O.와 10으로 나와요. 이 풀이는 켜진 이웃의 수를 세어 near == 1인지 물어요.
Pythonmain.py · 16 줄
n, t = map(int, input().split())cur = [1 if c == "O" else 0 for c in input()]total = 0for _ in range(t): nxt = [0] * n # 다음 순간은 새 리스트에 적는다: 모두가 '지금'을 보고 한꺼번에 바뀐다 for i in range(n): near = 0 # 켜진 이웃의 수 if i > 0: near += cur[i - 1] if i < n - 1: near += cur[i + 1] nxt[i] = 1 if cur[i] == 0 and near == 1 else 0 cur = nxt total += sum(cur)print("".join("O" if x else "." for x in cur))print(total)
JavaScriptmain.js · 18 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, t] = lines[0].split(" ").map(Number);let cur = [];for (let i = 0; i < n; i++) cur.push(lines[1][i] === "O" ? 1 : 0);let total = 0;for (let s = 0; s < t; s++) { const next = new Array(n).fill(0); // 다음 순간은 새 배열에 적는다 for (let i = 0; i < n; i++) { let near = 0; // 켜진 이웃의 수 if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] === 0 && near === 1 ? 1 : 0; total += next[i]; } cur = next;}console.log(cur.map((x) => (x ? "O" : ".")).join(""));console.log(total);
TypeScriptmain.ts · 20 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, t] = lines[0].split(" ").map(Number);let cur: number[] = [];for (let i = 0; i < n; i++) cur.push(lines[1][i] === "O" ? 1 : 0);let total = 0;for (let s = 0; s < t; s++) { const next: number[] = new Array<number>(n).fill(0); // 다음 순간은 새 배열에 적는다 for (let i = 0; i < n; i++) { let near = 0; // 켜진 이웃의 수 if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] === 0 && near === 1 ? 1 : 0; total += next[i]; } cur = next;}console.log(cur.map((x) => (x ? "O" : ".")).join(""));console.log(total);
JavaMain.java · 30 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] first = br.readLine().split(" "); int n = Integer.parseInt(first[0]), t = Integer.parseInt(first[1]); String row = br.readLine(); int[] cur = new int[n]; for (int i = 0; i < n; i++) cur[i] = row.charAt(i) == 'O' ? 1 : 0; int total = 0; for (int s = 0; s < t; s++) { int[] next = new int[n]; // 다음 순간은 새 배열에 적는다 for (int i = 0; i < n; i++) { int near = 0; // 켜진 이웃의 수 if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] == 0 && near == 1 ? 1 : 0; total += next[i]; } cur = next; } StringBuilder sb = new StringBuilder(); for (int x : cur) sb.append(x == 1 ? 'O' : '.'); System.out.println(sb); System.out.println(total); }}
C#Main.cs · 32 줄
using System;using System.Text;class Program{ static void Main() { string[] first = Console.ReadLine()!.Split(' '); int n = int.Parse(first[0]), t = int.Parse(first[1]); string row = Console.ReadLine()!; int[] cur = new int[n]; for (int i = 0; i < n; i++) cur[i] = row[i] == 'O' ? 1 : 0; int total = 0; for (int s = 0; s < t; s++) { int[] next = new int[n]; // 다음 순간은 새 배열에 적는다 for (int i = 0; i < n; i++) { int near = 0; // 켜진 이웃의 수 if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] == 0 && near == 1 ? 1 : 0; total += next[i]; } cur = next; } var sb = new StringBuilder(); foreach (int x in cur) sb.Append(x == 1 ? 'O' : '.'); Console.WriteLine(sb); Console.WriteLine(total); }}
C++main.cpp · 27 줄
#include <iostream>#include <string>#include <vector>using namespace std;int main() { int n, t; string row; cin >> n >> t >> row; vector<int> cur(n); for (int i = 0; i < n; i++) cur[i] = row[i] == 'O'; int total = 0; for (int s = 0; s < t; s++) { vector<int> next(n, 0); // 다음 순간은 새 vector에 적는다 for (int i = 0; i < n; i++) { int near = 0; // 켜진 이웃의 수 if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] == 0 && near == 1; total += next[i]; } cur = next; // vector의 = 는 내용을 통째로 복사한다 } for (int x : cur) cout << (x ? 'O' : '.'); cout << '\n' << total << '\n'; return 0;}
Cmain.c · 24 줄
#include <stdio.h>#include <string.h>int main(void) { int n, t; char row[201]; int cur[200], next[200]; if (scanf("%d %d %200s", &n, &t, row) != 3) return 0; for (int i = 0; i < n; i++) cur[i] = row[i] == 'O'; int total = 0; for (int s = 0; s < t; s++) { for (int i = 0; i < n; i++) { int near = 0; /* 켜진 이웃의 수 */ if (i > 0) near += cur[i - 1]; if (i < n - 1) near += cur[i + 1]; next[i] = cur[i] == 0 && near == 1; /* 다음 순간은 다른 배열에 적는다 */ total += next[i]; } memcpy(cur, next, sizeof(int) * n); /* C 배열은 = 로 옮길 수 없다 */ } for (int i = 0; i < n; i++) putchar(cur[i] ? 'O' : '.'); printf("\n%d\n", total); return 0;}
Craykonmain.cray · 53 줄
첫줄 = 콘솔.수들읽기();n = 첫줄[0];t = 첫줄[1];row = 콘솔.줄읽기();cur = [];반복 (i = 0; i < n; i++){ 만약 (row[i] == "O") { cur.넣기(1); } 아니면 { cur.넣기(0); }}total = 0;반복 (s = 0; s < t; s++){ next = 새목록(n, 0); // 다음 순간은 새 목록에 적는다 반복 (i = 0; i < n; i++) { near = 0; // 켜진 이웃의 수 만약 (i > 0) { near += cur[i - 1]; } 만약 (i < n - 1) { near += cur[i + 1]; } 만약 (cur[i] == 0 && near == 1) { next[i] = 1; total += 1; } } cur = next;}result = "";각각 (x 에서 cur){ 만약 (x == 1) { result += "O"; } 아니면 { result += "."; }}콘솔.쓰기(result);콘솔.쓰기(total);