{ }codelper
최댓값·최솟값겹친 반복P0238

일교차가 가장 큰 날

기상 관측소가 n일 동안 기온을 쟀다. 날마다 기온을 잰 횟수는 다를 수 있다. 첫 줄에 n이 주어진다. 다음 n줄에 하루에 한 줄씩, 그날 잰 횟수 k와 기온 k개가 빈칸으로 띄워 주어진다. 날 번호는 첫째 줄의 날이 1이고 하루씩 1 늘어난다. 하루의 일교차는 그날 잰 기온 가운데 가장 높은 기온에서 가장 낮은 기온을 뺀 값이다. 한 번만 잰 날의 일교차는 0이다. 세 줄을 출력하라. 첫째 줄에는 일교차가 가장 큰 날의 번호와 그 일교차를 출력한다.
그런 날이 여럿이면 가장 이른 날을 고른다. 둘째 줄에는 n일 동안의 가장 높은 기온과, 그 기온이 처음 나온 날의 번호를 출력한다. 셋째 줄에는 n일 동안의 가장 낮은 기온과, 그 기온이 마지막으로 나온 날의 번호를 출력한다. 각 줄의 두 수는 빈칸 하나로 띄운다.

입력
1 ≤ n ≤ 2,000, 1 ≤ k ≤ 24, -50 ≤ 기온 ≤ 50(정수)
출력
세 줄: 날 번호와 일교차, 최고 기온과 날 번호, 최저 기온과 날 번호
예시 1 · stdin
4
3 3 -2 7
1 5
4 -4 6 1 6
2 -4 0
stdout
3 10
7 1
-4 4
예시 2 · stdin
3
3 -5 -9 -3
2 -12 -7
2 -3 -1
stdout
1 6
-1 3
-12 2
main.py
입력(stdin)

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

$ 준비됐어요

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

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

목록 하나의 최댓값·최솟값은 Python max(a)·min(a), JS·TS Math.max(...a)·Math.min(...a), Java Math.max(x, y)를 반복문에서, C# a.Max()(LINQ) 또는 Math.Max, C++ std::minmax_element(둘을 한 번에), 크레이콘 수학.큰수·수학.작은수를 반복문에서 써요.
C에는 없어서 직접 비교해요.
첫째 함정은 처음 값이에요.
최고 기온을 0에서 시작하면 모두 영하인 입력에서 0이 답으로 남고, 최저 기온을 0에서 시작하면 모두 영상일 때 0이 남아요.
범위의 끝값 -50에서 시작해 >로 물어도, 모든 기온이 -50이면 한 번도 바뀌지 않아서 날 번호가 0으로 남아요.
첫 기온을 그대로 넣거나, 어떤 기온보다도 바깥인 값(Python None 검사, JS·TS -Infinity, Java Integer.MIN_VALUE, C# int.MinValue, C INT_MIN)에서 시작해요.
크레이콘에는 이런 끝값 상수가 없어서 그날의 첫 기온에서 시작하거나, "아직 못 봤다"는 표시(날 번호 0)를 함께 물어요.
둘째 함정은 같은 값일 때 고르는 쪽이에요.
>로 물으면 같은 값에서 바꾸지 않으니 처음 나온 것이 남고, >=(최솟값은 <=)로 물으면 같은 값에서도 바꾸니 마지막 것이 남아요.
이 문제는 일교차와 최고 기온은 처음 것, 최저 기온은 마지막 것이라 비교 기호가 서로 달라요.
셋째로, 날마다 기온 수가 다르니 한 줄을 다 읽어야 다음 날로 넘어가요.

Pythonmain.py · 16 줄
n = int(input())best_day = best_swing = Nonehi = hi_day = lo = lo_day = Nonefor day in range(1, n + 1):    temps = list(map(int, input().split()))[1:]    swing = max(temps) - min(temps)    if best_swing is None or swing > best_swing:  # 같으면 이른 날을 남긴다        best_day, best_swing = day, swing    for t in temps:        if hi is None or t > hi:  # 처음 나온 날: 같은 값이면 바꾸지 않는다            hi, hi_day = t, day        if lo is None or t <= lo:  # 마지막으로 나온 날: 같은 값이어도 바꾼다            lo, lo_day = t, dayprint(best_day, best_swing)print(hi, hi_day)print(lo, lo_day)
JavaScriptmain.js · 15 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);let bestDay = 0, bestSwing = -1;// 처음 값을 0으로 두면 모두 영하일 때 틀린다. 아무 기온보다 바깥인 Infinity에서 시작한다let hi = -Infinity, hiDay = 0, lo = Infinity, loDay = 0;for (let day = 1; day <= n; day++) {  const temps = lines[day].trim().split(/\s+/).map(Number).slice(1);  const swing = Math.max(...temps) - Math.min(...temps);  if (swing > bestSwing) { bestDay = day; bestSwing = swing; } // 같으면 이른 날  for (const t of temps) {    if (t > hi) { hi = t; hiDay = day; }   // 처음 나온 날    if (t <= lo) { lo = t; loDay = day; }  // 마지막으로 나온 날  }}console.log(`${bestDay} ${bestSwing}\n${hi} ${hiDay}\n${lo} ${loDay}`);
TypeScriptmain.ts · 16 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);let bestDay = 0, bestSwing = -1;// 처음 값을 0으로 두면 모두 영하일 때 틀린다. 아무 기온보다 바깥인 Infinity에서 시작한다let hi = -Infinity, hiDay = 0, lo = Infinity, loDay = 0;for (let day = 1; day <= n; day++) {  const temps: number[] = lines[day].trim().split(/\s+/).map(Number).slice(1);  const swing: number = Math.max(...temps) - Math.min(...temps);  if (swing > bestSwing) { bestDay = day; bestSwing = swing; } // 같으면 이른 날  for (const t of temps) {    if (t > hi) { hi = t; hiDay = day; }   // 처음 나온 날    if (t <= lo) { lo = t; loDay = day; }  // 마지막으로 나온 날  }}console.log(`${bestDay} ${bestSwing}\n${hi} ${hiDay}\n${lo} ${loDay}`);
JavaMain.java · 29 줄
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        int bestDay = 0, bestSwing = -1;        // 0이 아니라 int의 끝값에서 시작하면 어떤 기온이 와도 첫 값이 바로 들어간다        int hi = Integer.MIN_VALUE, hiDay = 0, lo = Integer.MAX_VALUE, loDay = 0;        for (int day = 1; day <= n; day++) {            StringTokenizer st = new StringTokenizer(in.readLine());            int k = Integer.parseInt(st.nextToken());            int dayHi = Integer.MIN_VALUE, dayLo = Integer.MAX_VALUE;            for (int i = 0; i < k; i++) {                int t = Integer.parseInt(st.nextToken());                dayHi = Math.max(dayHi, t);                dayLo = Math.min(dayLo, t);                if (t > hi) { hi = t; hiDay = day; }   // 처음 나온 날                if (t <= lo) { lo = t; loDay = day; }  // 마지막으로 나온 날            }            if (dayHi - dayLo > bestSwing) { bestDay = day; bestSwing = dayHi - dayLo; } // 같으면 이른 날        }        System.out.println(bestDay + " " + bestSwing);        System.out.println(hi + " " + hiDay);        System.out.println(lo + " " + loDay);    }}
C#Main.cs · 29 줄
using System; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        int bestDay = 0, bestSwing = -1;        // 0이 아니라 int의 끝값에서 시작하면 어떤 기온이 와도 첫 값이 바로 들어간다        int hi = int.MinValue, hiDay = 0, lo = int.MaxValue, loDay = 0;        for (int day = 1; day <= n; day++)        {            string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);            int dayHi = int.MinValue, dayLo = int.MaxValue;            for (int i = 1; i < p.Length; i++)            {                int t = int.Parse(p[i]);                dayHi = Math.Max(dayHi, t);                dayLo = Math.Min(dayLo, t);                if (t > hi) { hi = t; hiDay = day; }   // 처음 나온 날                if (t <= lo) { lo = t; loDay = day; }  // 마지막으로 나온 날            }            if (dayHi - dayLo > bestSwing) { bestDay = day; bestSwing = dayHi - dayLo; } // 같으면 이른 날        }        Console.WriteLine($"{bestDay} {bestSwing}");        Console.WriteLine($"{hi} {hiDay}");        Console.WriteLine($"{lo} {loDay}");    }}
C++main.cpp · 23 줄
#include <algorithm>#include <iostream>#include <vector> int main() {    int n, k;    std::cin >> n;    int bestDay = 0, bestSwing = -1;    int hi = 0, hiDay = 0, lo = 0, loDay = 0; // hiDay가 0이면 아직 아무 기온도 보지 않은 것    for (int day = 1; day <= n; day++) {        std::cin >> k;        std::vector<int> temps(k);        for (int &t : temps) std::cin >> t;        // minmax_element는 가장 작은 것과 가장 큰 것을 한 번에 찾는다        auto [mn, mx] = std::minmax_element(temps.begin(), temps.end());        if (*mx - *mn > bestSwing) { bestDay = day; bestSwing = *mx - *mn; } // 같으면 이른 날        for (int t : temps) {            if (hiDay == 0 || t > hi) { hi = t; hiDay = day; }   // 처음 나온 날            if (loDay == 0 || t <= lo) { lo = t; loDay = day; }  // 마지막으로 나온 날        }    }    std::cout << bestDay << ' ' << bestSwing << '\n' << hi << ' ' << hiDay << '\n' << lo << ' ' << loDay << '\n';}
Cmain.c · 24 줄
#include <limits.h>#include <stdio.h> int main(void) {    int n, k, t;    int bestDay = 0, bestSwing = -1;    /* 0이 아니라 int의 끝값(INT_MIN, INT_MAX)에서 시작한다 */    int hi = INT_MIN, hiDay = 0, lo = INT_MAX, loDay = 0;    scanf("%d", &n);    for (int day = 1; day <= n; day++) {        scanf("%d", &k);        int dayHi = INT_MIN, dayLo = INT_MAX;        for (int i = 0; i < k; i++) {            scanf("%d", &t);            if (t > dayHi) dayHi = t;            if (t < dayLo) dayLo = t;            if (t > hi) { hi = t; hiDay = day; }   /* 처음 나온 날 */            if (t <= lo) { lo = t; loDay = day; }  /* 마지막으로 나온 날 */        }        if (dayHi - dayLo > bestSwing) { bestDay = day; bestSwing = dayHi - dayLo; } /* 같으면 이른 날 */    }    printf("%d %d\n%d %d\n%d %d\n", bestDay, bestSwing, hi, hiDay, lo, loDay);    return 0;}
Craykonmain.cray · 38 줄
n = 콘솔.줄읽기().수로변환();bestDay = 0;bestSwing = -1;hi = 0;hiDay = 0; // 0이면 아직 아무 기온도 보지 않은 것lo = 0;loDay = 0;반복 (day = 1; day <= n; day++){    p = 콘솔.수들읽기();    // 그날의 첫 기온에서 시작한다(0에서 시작하면 모두 영하인 날에 틀린다)    dayHi = p[1];    dayLo = p[1];    반복 (i = 1; i < p.개수; i++)    {        t = p[i];        dayHi = 수학.큰수(dayHi, t);        dayLo = 수학.작은수(dayLo, t);        만약 (hiDay == 0 || t > hi)        {            hi = t;            hiDay = day; // 처음 나온 날        }        만약 (loDay == 0 || t <= lo)        {            lo = t;            loDay = day; // 마지막으로 나온 날        }    }    만약 (dayHi - dayLo > bestSwing)    {        bestDay = day; // 같으면 이른 날을 남긴다        bestSwing = dayHi - dayLo;    }}콘솔.쓰기(bestDay + " " + bestSwing);콘솔.쓰기(hi + " " + hiDay);콘솔.쓰기(lo + " " + loDay);