{ }codelper
ポインタ複数の戻り値P0073

ポインタで受け取る最小・最大・合計

一行目に n、二行目に n 個の整数が与えられる。
これらの最小値、最大値、合計を空白一つで区切って一行に出力せよ。
配列と長さ、そして結果三つを入れる呼び出し側の変数のアドレスを受け取り、そこに最小値・最大値・合計を書き込む関数 stats を作って解いてみよう(C はポインタ int *、C++ は参照 int& でもよい)。
main はこの関数を一度呼んでから三つの変数を出力する。

入力
1 ≤ n ≤ 100,000、すべての数は -1,000,000,000 以上 1,000,000,000 以下の整数
出力
一行:最小値 最大値 合計
例 1 · stdin
4
3 8 1 6
stdout
1 8 18
例 2 · stdin
3
-5 -2 -9
stdout
-9 -2 -16
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

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

ほかの言語では?言語別の解答を見る · 2 言語の解答

この問題は C・C++ だけを受け付けます。
呼び出し側の変数のアドレスを渡して関数に結果を書き込ませるポインタはこの二つにしかなく、Python・JavaScript・TypeScript・Java・Craykon にはありません(C# は unsafe の中だけ)。
C は void stats(const int *a, int n, int *mn, int *mx, long long *sum) で受け、stats(a, n, &mn, &mx, &sum) のように & でアドレスを渡し、関数の中で *mn = ... と書きます。
C++ は同じことを参照 int& mn でもっと簡単に書け、呼ぶときの & も要りません。
ほかの言語なら Python return lo, hi, s、C# のタプルや out int mn、Java は配列やオブジェクトにまとめて複数の値を返します。
落とし穴三つ:① int *mn ではなく int mn で受けると関数はコピーにだけ書き込み、呼び出し側の変数は最初の値のままです。
エラーも出ません。
② 合計は最大 10億 × 10万 = 10¹⁴ で int(約21億)を超えます。
long long と %lld を使います。
③ 最小値・最大値を 0 から始めると、すべて正のとき最小値が、すべて負のとき最大値が 0 になります。
先頭 a[0] から始めます。

C++main.cpp · 27 行
#include <iostream>#include <vector> // C++는 같은 일을 참조(&)로 한다. 포인터 int* 로 받아도 되지만 참조는 null이 될 수 없다void stats(const std::vector<int>& a, int& mn, int& mx, long long& sum) {    mn = mx = a[0];    sum = 0;    for (int v : a) {        if (v < mn) mn = v;        if (v > mx) mx = v;        sum += v;    }} int main() {    std::ios::sync_with_stdio(false);    std::cin.tie(nullptr);    int n;    std::cin >> n;    std::vector<int> a(n);    for (int& v : a) std::cin >> v;     int mn, mx;    long long sum;    stats(a, mn, mx, sum);    std::cout << mn << " " << mx << " " << sum << "\n";}
Cmain.c · 28 行
#include <stdio.h>#include <stdlib.h> /* 결과 세 개를 부른 쪽 변수의 주소로 받아서, 그 자리에 써 넣는다 */void stats(const int *a, int n, int *mn, int *mx, long long *sum) {    *mn = *mx = a[0];  /* 첫 칸으로 시작해야 모두 양수·모두 음수일 때도 맞다 */    *sum = 0;    for (int i = 0; i < n; i++) {        if (a[i] < *mn) *mn = a[i];        if (a[i] > *mx) *mx = a[i];        *sum += a[i];  /* 합은 long long: 10억 × 10만은 int를 넘는다 */    }} int main(void) {    int n;    scanf("%d", &n);    int *a = malloc(n * sizeof *a);    for (int i = 0; i < n; i++) scanf("%d", &a[i]);     int mn, mx;    long long sum;    stats(a, n, &mn, &mx, &sum);  /* 주소를 넘긴다 */    printf("%d %d %lld\n", mn, mx, sum);     free(a);    return 0;}