{ }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);