n 只萤火虫坐成一排。 这一排的状态用长度为 n 的字符串表示,O(大写英文字母 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()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
大家都看着“现在”同时变化,所以下一个状态必须写到和当前状态不同的数组里。 新建数组的写法各语言不一样。 Python 是 [0] * n,JS、TS 是 new Array(n).fill(0),Java、C# 是 new int[n],C++ 是 vector<int> next(n, 0),Craykon 是 新列表(n, 0)。 C 准备两个数组,用 memcpy 搬过去(C 的数组不能用 = 搬)。 陷阱一:nxt = cur 不是复制。 对 Python 列表、JS 数组、Java 和 C# 的数组、Craykon 列表来说,= 只是给同一个数组多起一个名字,所以一写下一个状态,当前状态就变了,右边的萤火虫看到的是已经变过的左邻居。 示例的答案会变成 .O..... 和 4。 只有 C++ 的 vector 在 cur = next 时把内容整个复制过去。 陷阱二:在这一排的两端只有一个邻居。 不先问 i > 0 就读 cur[i - 1],Python 会把 cur[-1] 读成最后一格,于是这一排的第一只和最后一只成了邻居。 示例的答案会变成 ..OO... 和 7。 同样的代码在 Java 里因 ArrayIndexOutOfBoundsException 停止,在 C# 里因 IndexOutOfRangeException 停止,Craykon 也会提示没有这个位置而停止。 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);