为了定聚会日期,问了 n 个人接下来 m 天里哪几天有空。 第一行给出人数 n 和天数 m,用一个空格分开。 接下来 n 行从 1 号开始依次给出每个人的回答,是长度为 m 的字符串。 字符串的第 k 个字符为大写 O 表示这个人第 k 天有空,为大写 X 表示没空。 两个人 i 和 j 共同有空的天数,是两人都为 O 的天数。 从第 1 行到第 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
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 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),Craykon 循环 (i = 0; i < n; i++)。 最常见的错误是把计数变量 count = 0 放在 j 循环外面。 这样换了一对也不会归零,前面几对的数会累加起来。 要在被计数的对象改变的地方,也就是 j 循环的里面紧接着归零。 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)) 的每个格子都是分开创建的。 Craykon 用循环每行放入一个 新列表(n, 0)。 读字符:Python、JS、TS、C#、C、C++、Craykon 用 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] = countfor 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));