友だち n 人が m 軒の店につけた評価の表を見て、集まる場所を選ぶ。 表の r 行目の j 番目の値は、r 番の友だちが j 番の店につけた評価である。 評価は整数で、行ったことがなく評価をつけていないマスには x が書かれている。 店ごとに、受けた評価のうち最も低い値(最低)と最も高い値(最高)を求める。 x は数えない。 評価を一つも受けていない店は選ばない。 最低が最も高い店を選ぶ。 最低が同じ店が複数あれば、その中で最高が最も高い店を、それも同じなら番号が最も小さい店を選ぶ。 次に、選んだ店を一番気に入っている友だちの数を数える。 選んだ店に評価をつけていて、その評価が自分のつけたすべての評価の中で最も高い値と等しい友だちを数える(最も高い値を複数の店につけていても数える)。 一行目に n と m が空白一つで区切って与えられる。 続く n 行に、行ごとに m 個の値が空白一つで区切って与えられる。 一行目に選んだ店の番号、最低、最高を空白一つで区切って出力し、二行目にその店を一番気に入っている友だちの数を出力せよ。 すべての店が評価を一つも受けていなければ、0 を一行だけ出力せよ。
入力
1 ≤ n ≤ 200。 1 ≤ m ≤ 200。 各値は x か、−100 以上 100 以下の整数
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);}