친구 n명이 식당 m곳에 준 별점 표를 보고 모임 장소를 고른다.
표의 r번째 줄 j번째 값은 r번 친구가 j번 식당에 준 별점이다.
별점은 정수이고, 가 보지 않아 별점을 주지 않은 칸에는 x가 적혀 있다.
식당마다 받은 별점 가운데 가장 낮은 값(최저)과 가장 높은 값(최고)을 구한다. x는 세지 않는다.
별점을 하나도 받지 못한 식당은 고르지 않는다.
최저가 가장 높은 식당을 고른다.
최저가 같은 식당이 여럿이면 그 가운데 최고가 가장 높은 식당을, 그것도 같으면 번호가 가장 작은 식당을 고른다.
그다음 고른 식당을 가장 좋아하는 친구의 수를 센다.
고른 식당에 별점을 주었고, 그 별점이 자기가 준 모든 별점 가운데 가장 높은 값과 같은 친구를 센다(가장 높은 값을 여러 식당에 주었어도 센다).
첫 줄에 n과 m이 빈칸 하나로 띄워 주어진다.
다음 n줄에 줄마다 m개의 값이 빈칸 하나로 띄워 주어진다.
첫 줄에 고른 식당의 번호, 최저, 최고를 빈칸 하나로 띄워 출력하고, 둘째 줄에 그 식당을 가장 좋아하는 친구의 수를 출력하라.
모든 식당이 별점을 하나도 받지 못했으면 0 한 줄만 출력하라.
입력
1 ≤ n ≤ 200. 1 ≤ m ≤ 200. 각 값은 x이거나 −100 이상 100 이하의 정수
출력
첫 줄에 식당 번호, 최저, 최고. 둘째 줄에 친구 수. 고를 식당이 없으면 0 한 줄
예시 1 · stdin
3 4
5 3 x 4
2 3 x 4
x 3 x -1
stdout
2 3 3
1
예시 2 · stdin
2 2
x x
x x
stdout
0
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
가장 작은 값·큰 값은 Python min(col)·max(col), JS·TS Math.min(...col)·Math.max(...col), C# col.Min()·col.Max(), C++ std::minmax_element로 한 번에 구하고, C·Java·크레이콘은 반복문에서 수학.작은수(lo, v)처럼 하나씩 견줘요. 함정 ① 값이 하나도 없을 때가 언어마다 달라요. Python min([])은 ValueError로 멈추지만 JS Math.min()은 Infinity, Math.max()는 -Infinity를 돌려줘요. 그래서 별점이 없는 식당을 건너뛰지 않으면 JS에서는 최저가 Infinity인 그 식당이 뽑혀요(첫 예시에서 3 Infinity -Infinity가 나와요). 값을 모은 목록이 비었는지 먼저 확인해요. ② 반복문으로 구할 때 0에서 시작하면 안 돼요. 별점이 −5, −3뿐이면 최고가 0이 되고, 5, 3뿐이면 최저가 0이 돼요. C INT_MAX·INT_MIN, Java Integer.MAX_VALUE·Integer.MIN_VALUE에서 시작하거나, 크레이콘 풀이처럼 처음 만난 별점에서 시작해요. ③ 읽은 값을 수로 바꾸지 않고 견주면 문자열 순서라 "9"가 "10"보다 커요. ④ 최저가 같으면 최고로 가르는 견주기는 Python 튜플 (lo, hi) > (best_lo, best_hi)와 C++ std::pair의 >가 앞의 값부터 차례로 해 줘요. C# 튜플에는 >가 없어 key.CompareTo(bestKey) > 0으로 써요. JS·TS에서 [lo, hi] > [bestLo, bestHi]라고 쓰면 배열이 문자열 "9,9", "10,10"으로 바뀌어 견줘져서 틀려요. lo > bestLo || (lo === bestLo && hi > bestHi)로 풀어 써요. 최저만 견주고 최고를 빠뜨려도 틀려요. ⑤ 번호가 작은 식당부터 보면서 >로 바꿔야 같을 때 번호가 작은 식당이 남아요. >=로 쓰면 나중 식당으로 바뀌어요. ⑥ 친구의 가장 높은 별점을 구할 때도 x를 빼야 해요. Python에서 None이 섞인 목록에 max(row)를 쓰면 TypeError예요. C#의 int?[]는 row.Max()가 null을 빼고 구해 줘요. 크레이콘은 값이 없는 칸을 빈값으로 두고 v == 빈값으로 걸러요(빈값을 수학.큰수에 넣으면 멈춰요). 고른 식당에 별점을 주지 않은 친구는 세지 않아요.
Pythonmain.py · 32 줄
import sysdef main(): data = sys.stdin.read().split() n, m = int(data[0]), int(data[1]) # 별점이 없는 칸은 None으로 둔다 grid = [[None if tok == "x" else int(tok) for tok in data[2 + r * m:2 + (r + 1) * m]] for r in range(n)] best = 0 # 고른 식당 번호(0이면 아직 없음) best_key = None for j in range(m): col = [row[j] for row in grid if row[j] is not None] if not col: # min([])은 ValueError다: 별점이 없는 식당은 건너뛴다 continue key = (min(col), max(col)) # 튜플은 앞의 값부터 차례로 견준다 if best == 0 or key > best_key: # >라서 같으면 번호가 작은 식당이 남는다 best, best_key = j + 1, key if best == 0: print(0) return fans = 0 for row in grid: mine = row[best - 1] if mine is not None and mine == max(v for v in row if v is not None): fans += 1 print(best, best_key[0], best_key[1]) print(fans)main()
JavaScriptmain.js · 35 줄
const tokens = require("fs").readFileSync(0, "utf8").split(/\s+/).filter((s) => s !== "");const n = Number(tokens[0]);const m = Number(tokens[1]);// 별점이 없는 칸은 null로 둔다. 문자열인 채로 견주면 "9" > "10"이라 수로 바꾼다const grid = [];for (let r = 0; r < n; r++) { grid.push(tokens.slice(2 + r * m, 2 + (r + 1) * m).map((t) => (t === "x" ? null : Number(t))));}let best = 0; // 고른 식당 번호(0이면 아직 없음)let bestLo = 0;let bestHi = 0;for (let j = 0; j < m; j++) { const col = grid.map((row) => row[j]).filter((v) => v !== null); if (col.length === 0) continue; // Math.min()은 Infinity다: 별점이 없는 식당은 건너뛴다 const lo = Math.min(...col); const hi = Math.max(...col); // 배열끼리 >로 견주면 문자열로 바뀌므로 값을 하나씩 견준다 if (best === 0 || lo > bestLo || (lo === bestLo && hi > bestHi)) { best = j + 1; bestLo = lo; bestHi = hi; }}if (best === 0) { console.log(0);} else { let fans = 0; for (const row of grid) { const mine = row[best - 1]; if (mine !== null && mine === Math.max(...row.filter((v) => v !== null))) fans++; } console.log(best + " " + bestLo + " " + bestHi + "\n" + fans);}
TypeScriptmain.ts · 38 줄
import { readFileSync } from "node:fs";const tokens: string[] = readFileSync(0, "utf8").split(/\s+/).filter((s) => s !== "");const n: number = Number(tokens[0]);const m: number = Number(tokens[1]);// 별점이 없는 칸은 null로 둔다. 문자열인 채로 견주면 "9" > "10"이라 수로 바꾼다const grid: (number | null)[][] = [];for (let r = 0; r < n; r++) { grid.push(tokens.slice(2 + r * m, 2 + (r + 1) * m).map((t) => (t === "x" ? null : Number(t))));}const rated = (v: number | null): v is number => v !== null;let best = 0; // 고른 식당 번호(0이면 아직 없음)let bestLo = 0;let bestHi = 0;for (let j = 0; j < m; j++) { const col: number[] = grid.map((row) => row[j]).filter(rated); if (col.length === 0) continue; // Math.min()은 Infinity다: 별점이 없는 식당은 건너뛴다 const lo: number = Math.min(...col); const hi: number = Math.max(...col); // 배열끼리 >로 견주면 문자열로 바뀌므로 값을 하나씩 견준다 if (best === 0 || lo > bestLo || (lo === bestLo && hi > bestHi)) { best = j + 1; bestLo = lo; bestHi = hi; }}if (best === 0) { console.log(0);} else { let fans = 0; for (const row of grid) { const mine = row[best - 1]; if (mine !== null && mine === Math.max(...row.filter(rated))) fans++; } console.log(best + " " + bestLo + " " + bestHi + "\n" + fans);}
JavaMain.java · 54 줄
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()); Integer[][] grid = new Integer[n][m]; // 별점이 없는 칸은 null for (int r = 0; r < n; r++) { st = new StringTokenizer(in.readLine()); for (int j = 0; j < m; j++) { String tok = st.nextToken(); grid[r][j] = tok.equals("x") ? null : Integer.valueOf(tok); } } int best = 0, bestLo = 0, bestHi = 0; // best가 0이면 아직 고른 식당이 없다 for (int j = 0; j < m; j++) { // 0이 아니라 가장 큰 값·가장 작은 값에서 시작해야 음수 별점도 맞게 나온다 int lo = Integer.MAX_VALUE, hi = Integer.MIN_VALUE, count = 0; for (int r = 0; r < n; r++) { if (grid[r][j] == null) continue; lo = Math.min(lo, grid[r][j]); hi = Math.max(hi, grid[r][j]); count++; } if (count == 0) continue; // 별점이 없는 식당은 건너뛴다 if (best == 0 || lo > bestLo || (lo == bestLo && hi > bestHi)) { best = j + 1; bestLo = lo; bestHi = hi; } } if (best == 0) { System.out.println(0); return; } int fans = 0; for (int r = 0; r < n; r++) { if (grid[r][best - 1] == null) continue; int top = Integer.MIN_VALUE; for (int j = 0; j < m; j++) { if (grid[r][j] != null) top = Math.max(top, grid[r][j]); } if (grid[r][best - 1] == top) fans++; } System.out.println(best + " " + bestLo + " " + bestHi); System.out.println(fans); }}
C#Main.cs · 47 줄
using System;using System.Linq;class Program{ static void Main() { string[] head = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(head[0]), m = int.Parse(head[1]); var grid = new int?[n][]; // 별점이 없는 칸은 null for (int r = 0; r < n; r++) { grid[r] = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries) .Select(tok => tok == "x" ? (int?)null : int.Parse(tok)).ToArray(); } int best = 0; // 고른 식당 번호(0이면 아직 없음) (int lo, int hi) bestKey = (0, 0); for (int j = 0; j < m; j++) { int[] col = grid.Where(row => row[j] != null).Select(row => row[j].Value).ToArray(); if (col.Length == 0) continue; // 빈 배열의 Min()은 예외다: 별점이 없는 식당은 건너뛴다 var key = (col.Min(), col.Max()); // 튜플에는 > 연산자가 없어서 CompareTo로 앞의 값부터 견준다 if (best == 0 || key.CompareTo(bestKey) > 0) { best = j + 1; bestKey = key; } } if (best == 0) { Console.WriteLine(0); return; } int fans = 0; foreach (int?[] row in grid) { int? mine = row[best - 1]; // int?의 Max()는 null을 빼고 구한다 if (mine != null && mine == row.Max()) fans++; } Console.WriteLine($"{best} {bestKey.lo} {bestKey.hi}"); Console.WriteLine(fans); }}
C++main.cpp · 53 줄
#include <algorithm>#include <iostream>#include <optional>#include <string>#include <utility>#include <vector>int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, m; std::cin >> n >> m; // 별점이 없는 칸은 std::nullopt std::vector<std::vector<std::optional<int>>> grid(n, std::vector<std::optional<int>>(m)); for (auto& row : grid) { for (auto& cell : row) { std::string tok; std::cin >> tok; if (tok != "x") cell = std::stoi(tok); } } int best = 0; // 고른 식당 번호(0이면 아직 없음) std::pair<int, int> bestKey; for (int j = 0; j < m; j++) { std::vector<int> col; for (const auto& row : grid) { if (row[j]) col.push_back(*row[j]); } if (col.empty()) continue; // 별점이 없는 식당은 건너뛴다 auto [lo, hi] = std::minmax_element(col.begin(), col.end()); std::pair<int, int> key(*lo, *hi); // pair는 앞의 값부터 차례로 견준다 if (best == 0 || key > bestKey) { best = j + 1; bestKey = key; } } if (best == 0) { std::cout << 0 << '\n'; return 0; } int fans = 0; for (const auto& row : grid) { if (!row[best - 1]) continue; int top = *row[best - 1]; for (const auto& cell : row) { if (cell) top = std::max(top, *cell); } if (*row[best - 1] == top) fans++; } std::cout << best << ' ' << bestKey.first << ' ' << bestKey.second << '\n' << fans << '\n';}
Cmain.c · 54 줄
#include <limits.h>#include <stdio.h>#include <stdlib.h>#define MAXN 200#define NONE INT_MIN /* 별점이 없는 칸 */static int grid[MAXN][MAXN];int main(void) { int n, m; char tok[16]; scanf("%d %d", &n, &m); for (int r = 0; r < n; r++) { for (int j = 0; j < m; j++) { scanf("%15s", tok); grid[r][j] = tok[0] == 'x' ? NONE : atoi(tok); } } int best = 0, bestLo = 0, bestHi = 0; /* best가 0이면 아직 고른 식당이 없다 */ for (int j = 0; j < m; j++) { /* 0이 아니라 가장 큰 값·가장 작은 값에서 시작해야 음수 별점도 맞게 나온다 */ int lo = INT_MAX, hi = INT_MIN, count = 0; for (int r = 0; r < n; r++) { if (grid[r][j] == NONE) continue; if (grid[r][j] < lo) lo = grid[r][j]; if (grid[r][j] > hi) hi = grid[r][j]; count++; } if (count == 0) continue; /* 별점이 없는 식당은 건너뛴다 */ if (best == 0 || lo > bestLo || (lo == bestLo && hi > bestHi)) { best = j + 1; bestLo = lo; bestHi = hi; } } if (best == 0) { puts("0"); return 0; } int fans = 0; for (int r = 0; r < n; r++) { if (grid[r][best - 1] == NONE) continue; int top = INT_MIN; for (int j = 0; j < m; j++) { if (grid[r][j] != NONE && grid[r][j] > top) top = grid[r][j]; } if (grid[r][best - 1] == top) fans++; } printf("%d %d %d\n%d\n", best, bestLo, bestHi, fans); return 0;}
Craykonmain.cray · 95 줄
head = 콘솔.수들읽기();n = head[0];m = head[1];// 별점이 없는 칸은 빈값으로 둔다grid = [];반복 (r = 0; r < n; r++){ row = []; 각각 (tok 에서 콘솔.줄읽기().공백제거().나누기(" ")) { 만약 (tok == "x") { row.넣기(빈값); } 아니면 { row.넣기(tok.수로변환()); } } grid.넣기(row);}// best가 0이면 아직 고른 식당이 없다best = 0;bestLo = 0;bestHi = 0;반복 (j = 0; j < m; j++){ // 0이 아니라 처음 만난 별점에서 시작해야 음수 별점도 맞게 나온다 count = 0; lo = 0; hi = 0; 반복 (r = 0; r < n; r++) { v = grid[r][j]; 만약 (v == 빈값) { 건너뛰기; } 만약 (count == 0) { lo = v; hi = v; } 아니면 { lo = 수학.작은수(lo, v); hi = 수학.큰수(hi, v); } count++; } // 별점이 없는 식당은 건너뛴다 만약 (count == 0) { 건너뛰기; } 만약 (best == 0 || lo > bestLo || lo == bestLo && hi > bestHi) { best = j + 1; bestLo = lo; bestHi = hi; }}만약 (best == 0){ 콘솔.쓰기(0);}아니면{ fans = 0; 각각 (row 에서 grid) { mine = row[best - 1]; 만약 (mine == 빈값) { 건너뛰기; } // 이 친구가 준 가장 높은 별점: mine에서 시작하면 된다 top = mine; 각각 (v 에서 row) { 만약 (v != 빈값) { top = 수학.큰수(top, v); } } 만약 (mine == top) { fans++; } } 콘솔.쓰기(best + " " + bestLo + " " + bestHi); 콘솔.쓰기(fans);}