{ }codelper
겹친 반복2차원 목록P0234

둘 다 비는 날 세기 표

모임 날짜를 정하려고 n명에게 앞으로 m일 동안 시간이 되는 날을 물었다. 첫 줄에 사람 수 n과 날 수 m이 빈칸 하나로 띄워 주어진다. 다음 n줄에는 1번 사람부터 차례로 한 사람의 답이 길이 m인 문자열로 주어진다. 문자열의 k째 글자는 그 사람이 k째 날에 시간이 되면 대문자 O, 안 되면 대문자 X다. 두 사람 i와 j가 함께 비는 날의 수는, 두 사람이 모두 O인 날의 수다. 첫째 줄부터 n째 줄까지, i째 줄에 j = 1부터 n까지 i와 j가 함께 비는 날의 수를 빈칸 하나씩으로 띄워 출력하라. i와 j가 같으면 그 사람이 혼자 비는 날의 수(O의 개수)를 쓴다. 마지막 줄에는 서로 다른 두 사람 가운데 함께 비는 날이 가장 많은 쌍의 번호 i와 j를 i < j로 빈칸 하나로 띄워 출력하라. 그런 쌍이 여럿이면 i가 가장 작은 것을, 그래도 여럿이면 j가 가장 작은 것을 출력한다. 함께 비는 날이 모든 쌍에서 0이면 1 2를 출력한다.

입력
2 ≤ n ≤ 100, 1 ≤ m ≤ 100, 답은 대문자 O와 X로만 된 길이 m인 문자열
출력
n줄: n × n 표 / 마지막 줄: 함께 비는 날이 가장 많은 두 사람의 번호
예시 1 · stdin
4 5
OOXOX
XOOOX
OOOOO
XXXXO
stdout
3 2 3 0
2 3 3 0
3 3 5 1
0 0 1 1
1 3
예시 2 · stdin
2 3
OXO
XOX
stdout
2 0
0 1
1 2
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

세 겹 반복이에요: 사람 i, 사람 j, 날 k.
반복 머리는 Python for i in range(n):, JS·TS·Java·C#·C·C++ for (int i = 0; i < n; i++)(JS·TS는 let), 크레이콘 반복 (i = 0; i < n; i++)예요.
가장 흔한 실수는 세는 변수 count = 0을 j 반복 바깥에 두는 거예요.
그러면 쌍이 바뀌어도 0으로 돌아가지 않아 앞의 쌍의 수가 쌓여요.
셀 것이 바뀌는 곳, 곧 j 반복 바로 안에서 0으로 만들어요.
C에서 반복 변수를 함수 맨 앞에 미리 선언해 두고 안쪽 for의 시작 칸을 비우면(for (; j < n; j++)) j가 다시 시작하지 않아 첫 사람만 살펴요.
for (int j = i + 1; ...)처럼 반복마다 새로 정해요.
표 만들기도 언어마다 달라요.
Python [[0] * n] * n은 같은 줄 하나를 n번 가리켜서 한 칸을 고치면 모든 줄의 같은 칸이 바뀌니 [[0] * n for _ in range(n)]로 줄마다 새로 만들어요.
JS·TS도 new Array(n).fill(new Array(n).fill(0))이면 같은 문제가 생겨서 Array.from({ length: n }, () => new Array(n).fill(0))을 써요.
Java new int[n][n], C# new int[n, n], C int common[100][100], C++ std::vector<std::vector<int>>(n, std::vector<int>(n))은 칸마다 따로 만들어져요.
크레이콘은 반복으로 줄마다 새목록(n, 0)을 넣어요.
글자 읽기는 Python·JS·TS·C#·C·C++·크레이콘 rows[i][k], Java rows[i].charAt(k)예요.
(i, j)와 (j, i)는 값이 같으니 j ≥ i만 세고 두 칸에 같이 넣으면 일이 절반쯤으로 줄어요.
가장 많은 쌍을 찾을 때는 j를 i + 1부터 돌려야 자기 자신과의 칸(대각선)을 고르지 않고, 차례대로 돌며 >로 바꿔야 같을 때 앞의 쌍이 남아요.
출력 번호는 배열 번호에 1을 더해요.

Pythonmain.py · 23 줄
n, m = map(int, input().split())rows = [input() for _ in range(n)] # common[i][j]: i와 j가 둘 다 비는 날의 수. (i, j)와 (j, i)는 같으니 j >= i만 세고 거울처럼 채운다common = [[0] * n for _ in range(n)]for i in range(n):    for j in range(i, n):        count = 0  # 쌍마다 새로 센다        for k in range(m):            if rows[i][k] == "O" and rows[j][k] == "O":                count += 1        common[i][j] = common[j][i] = count for row in common:    print(" ".join(map(str, row))) # 서로 다른 두 사람만: j는 i + 1부터. 차례대로 돌며 >로 바꾸면 같을 때 앞의 쌍이 남는다best_i, best_j = 0, 1for i in range(n):    for j in range(i + 1, n):        if common[i][j] > common[best_i][best_j]:            best_i, best_j = i, jprint(best_i + 1, best_j + 1)
JavaScriptmain.js · 29 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, m] = lines[0].trim().split(/\s+/).map(Number);const rows = lines.slice(1, 1 + n).map((s) => s.trim()); // common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다const common = Array.from({ length: n }, () => new Array(n).fill(0));for (let i = 0; i < n; i++) {  for (let j = i; j < n; j++) {    let count = 0; // 쌍마다 새로 센다    for (let k = 0; k < m; k++) {      if (rows[i][k] === "O" && rows[j][k] === "O") count++;    }    common[i][j] = common[j][i] = count;  }} const out = common.map((row) => row.join(" "));let bi = 0;let bj = 1;for (let i = 0; i < n; i++) {  for (let j = i + 1; j < n; j++) {    if (common[i][j] > common[bi][bj]) {      bi = i;      bj = j;    }  }}out.push(`${bi + 1} ${bj + 1}`);console.log(out.join("\n"));
TypeScriptmain.ts · 30 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, m] = lines[0].trim().split(/\s+/).map(Number);const rows: string[] = lines.slice(1, 1 + n).map((s) => s.trim()); // common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다const common: number[][] = Array.from({ length: n }, () => new Array<number>(n).fill(0));for (let i = 0; i < n; i++) {  for (let j = i; j < n; j++) {    let count = 0; // 쌍마다 새로 센다    for (let k = 0; k < m; k++) {      if (rows[i][k] === "O" && rows[j][k] === "O") count++;    }    common[i][j] = common[j][i] = count;  }} const out: string[] = common.map((row) => row.join(" "));let bi = 0;let bj = 1;for (let i = 0; i < n; i++) {  for (let j = i + 1; j < n; j++) {    if (common[i][j] > common[bi][bj]) {      bi = i;      bj = j;    }  }}out.push(`${bi + 1} ${bj + 1}`);console.log(out.join("\n"));
JavaMain.java · 46 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        StringTokenizer st = new StringTokenizer(in.readLine());        int n = Integer.parseInt(st.nextToken()), m = Integer.parseInt(st.nextToken());        String[] rows = new String[n];        for (int i = 0; i < n; i++) rows[i] = in.readLine().trim();         // common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다        int[][] common = new int[n][n];        for (int i = 0; i < n; i++) {            for (int j = i; j < n; j++) {                int count = 0; // 쌍마다 새로 센다                for (int k = 0; k < m; k++) {                    if (rows[i].charAt(k) == 'O' && rows[j].charAt(k) == 'O') count++;                }                common[i][j] = common[j][i] = count;            }        }         StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if (j > 0) out.append(' ');                out.append(common[i][j]);            }            out.append('\n');        }        int bi = 0, bj = 1;        for (int i = 0; i < n; i++) {            for (int j = i + 1; j < n; j++) {                if (common[i][j] > common[bi][bj]) {                    bi = i;                    bj = j;                }            }        }        out.append(bi + 1).append(' ').append(bj + 1).append('\n');        System.out.print(out);    }}
C#Main.cs · 53 줄
using System;using System.Text; class Program{    static void Main()    {        string[] nm = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int n = int.Parse(nm[0]), m = int.Parse(nm[1]);        var rows = new string[n];        for (int i = 0; i < n; i++) rows[i] = Console.ReadLine().Trim();         // common[i, j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다        var common = new int[n, n];        for (int i = 0; i < n; i++)        {            for (int j = i; j < n; j++)            {                int count = 0; // 쌍마다 새로 센다                for (int k = 0; k < m; k++)                {                    if (rows[i][k] == 'O' && rows[j][k] == 'O') count++;                }                common[i, j] = common[j, i] = count;            }        }         var out_ = new StringBuilder();        for (int i = 0; i < n; i++)        {            for (int j = 0; j < n; j++)            {                if (j > 0) out_.Append(' ');                out_.Append(common[i, j]);            }            out_.Append('\n');        }        int bi = 0, bj = 1;        for (int i = 0; i < n; i++)        {            for (int j = i + 1; j < n; j++)            {                if (common[i, j] > common[bi, bj])                {                    bi = i;                    bj = j;                }            }        }        out_.Append(bi + 1).Append(' ').Append(bj + 1).Append('\n');        Console.Write(out_);    }}
C++main.cpp · 38 줄
#include <iostream>#include <string>#include <vector> int main() {    std::ios::sync_with_stdio(false);    int n, m;    std::cin >> n >> m;    std::vector<std::string> rows(n);    for (auto& r : rows) std::cin >> r;     // common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다    std::vector<std::vector<int>> common(n, std::vector<int>(n, 0));    for (int i = 0; i < n; i++) {        for (int j = i; j < n; j++) {            int count = 0; // 쌍마다 새로 센다            for (int k = 0; k < m; k++) {                if (rows[i][k] == 'O' && rows[j][k] == 'O') count++;            }            common[i][j] = common[j][i] = count;        }    }     for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) std::cout << (j ? " " : "") << common[i][j];        std::cout << '\n';    }    int bi = 0, bj = 1;    for (int i = 0; i < n; i++) {        for (int j = i + 1; j < n; j++) {            if (common[i][j] > common[bi][bj]) {                bi = i;                bj = j;            }        }    }    std::cout << bi + 1 << ' ' << bj + 1 << '\n';}
Cmain.c · 37 줄
#include <stdio.h> static char rows[100][101];static int common[100][100]; int main(void) {    int n, m;    scanf("%d %d", &n, &m);    for (int i = 0; i < n; i++) scanf("%100s", rows[i]);     /* common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다 */    for (int i = 0; i < n; i++) {        for (int j = i; j < n; j++) {            int count = 0; /* 쌍마다 새로 센다 */            for (int k = 0; k < m; k++) {                if (rows[i][k] == 'O' && rows[j][k] == 'O') count++;            }            common[i][j] = common[j][i] = count;        }    }     for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) printf(j ? " %d" : "%d", common[i][j]);        printf("\n");    }    int bi = 0, bj = 1;    for (int i = 0; i < n; i++) {        for (int j = i + 1; j < n; j++) {            if (common[i][j] > common[bi][bj]) {                bi = i;                bj = j;            }        }    }    printf("%d %d\n", bi + 1, bj + 1);    return 0;}
Craykonmain.cray · 50 줄
nm = 콘솔.수들읽기();n = nm[0];m = nm[1];rows = [];반복 (i = 0; i < n; i++){    rows.넣기(콘솔.줄읽기().공백제거());} // common[i][j]: i와 j가 둘 다 비는 날의 수. j >= i만 세고 거울처럼 채운다common = [];반복 (i = 0; i < n; i++){    common.넣기(새목록(n, 0));}반복 (i = 0; i < n; i++){    반복 (j = i; j < n; j++)    {        count = 0; // 쌍마다 새로 센다        반복 (k = 0; k < m; k++)        {            만약 (rows[i][k] == "O" && rows[j][k] == "O")            {                count++;            }        }        common[i][j] = count;        common[j][i] = count;    }} 반복 (i = 0; i < n; i++){    콘솔.쓰기(common[i].잇기(" "));}bi = 0;bj = 1;반복 (i = 0; i < n; i++){    반복 (j = i + 1; j < n; j++)    {        만약 (common[i][j] > common[bi][bj])        {            bi = i;            bj = j;        }    }}콘솔.쓰기(bi + 1 + " " + (bj + 1));