{ }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()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 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(二つを一度に)、Craykon はループの中で 数学.大きい方・数学.小さい方 を使います。
C にはないので自分で比べます。
一つ目の落とし穴は最初の値です。
最高気温を 0 から始めると、すべて氷点下の入力で 0 が答えに残り、最低気温を 0 から始めると、すべてプラスのときに 0 が残ります。
範囲の端の値 -50 から始めて > で聞いても、すべての気温が -50 なら一度も変わらず、日の番号が 0 のまま残ります。
最初の気温をそのまま入れるか、どの気温よりも外側の値(Python は None の確認、JS・TS -Infinity、Java Integer.MIN_VALUE、C# int.MinValue、C INT_MIN)から始めます。
Craykon にはこうした端の値の定数がないので、その日の最初の気温から始めるか、「まだ見ていない」という印(日の番号 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);