{ }codelper
break・continueP0223

宅配トラックに順に積む

宅配トラックに、決まった順番で箱を積む。
一行目に箱の数 n、トラックに積める重さの合計 C、箱一つの重さの上限 L が空白で区切って与えられる。
二行目に n 個の箱の重さが積む順に空白で区切って与えられる。
箱の番号はこの順に 1 番から付ける。
箱を 1 番から一つずつ見て、次の規則を上から順に当てはめる。
箱の重さが L より重ければ、その箱は積まずに別便で送り、次の箱へ進む。
そうでないとき、その箱を積むと積んだ重さの合計が C より大きくなるなら、その箱で止める。
止めたら、その箱とそれより後の箱はどれも、積みも別便で送りもしない。
後ろに軽い箱があっても同じである。
どちらでもなければその箱を積む。
積んだあとの合計がちょうど C でもよい。
積んだ箱の数、積んだ重さの合計、別便で送った箱の数、止めた箱の番号を空白一つずつで区切って一行に出力せよ。
最後の箱まで見ても止めなかったなら、止めた箱の番号の代わりに 0 を出力する。

入力
1 ≤ n ≤ 10,000、1 ≤ L ≤ C ≤ 1,000,000、1 ≤ 箱の重さ ≤ 1,000,000。
すべて整数
出力
積んだ箱の数、積んだ重さの合計、別便の箱の数、止めた箱の番号(止めなければ 0)を一行
例 1 · stdin
6 15 8
5 9 6 7 2 1
stdout
2 11 1 4
例 2 · stdin
5 10 5
4 4 9 1 3
stdout
3 9 1 5
main.py
入力(stdin)

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

$ 準備完了

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

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

この箱だけを飛ばすのは continue、ループ全体を終えるのは break です。
Python・JS・TS・Java・C#・C・C++ はどれも同じ言葉を使い、Craykon は 次へ と 抜ける です。
この二つを取り違えるのがいちばん多い間違いです。
あふれるときに continue を使うと後ろの軽い箱を積み続けてしまい、重い箱で break を使うと後ろの箱を一つも見ません。
規則の順番も大事です。
あふれるかどうかを先に聞くと、あふれる位置に来た重い箱で止まってしまいますが、その箱は別便で送らなければなりません。
合計がちょうど C でも積むので、>= ではなく > で聞きます。
break はいちばん内側のループ一つだけを終え、C・C++・Java・JS・TS・C# の switch の中で使うと switch だけを抜けます(Craykon の 選択 の中の 抜ける も同じです)。
止めた番号を別に持たずに、Python の for … else(最後まで break せずに回ったときだけ else が動く)を使うこともできます。
番号を 0 から数えるループなら、出力するときに 1 を足します。

Pythonmain.py · 14 行
n, cap, limit = map(int, input().split())boxes = list(map(int, input().split()))loaded = total = sent = 0stop = 0for i, w in enumerate(boxes, start=1):    if w > limit:          # 너무 무거운 상자: 따로 보내고 다음 상자로        sent += 1        continue    if total + w > cap:    # 실으면 넘친다: 여기서 아예 멈춘다        stop = i        break    loaded += 1    total += wprint(loaded, total, sent, stop)
JavaScriptmain.js · 19 行
const [n, cap, limit, ...boxes] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let loaded = 0;let total = 0;let sent = 0;let stop = 0;for (let i = 0; i < n; i++) {  const w = boxes[i];  if (w > limit) {    sent++;    continue; // 이 상자만 건너뛴다  }  if (total + w > cap) {    stop = i + 1;    break; // 반복 전체를 끝낸다  }  loaded++;  total += w;}console.log(`${loaded} ${total} ${sent} ${stop}`);
TypeScriptmain.ts · 20 行
import { readFileSync } from "node:fs";const [n, cap, limit, ...boxes]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let loaded = 0;let total = 0;let sent = 0;let stop = 0;for (let i = 0; i < n; i++) {  const w: number = boxes[i];  if (w > limit) {    sent++;    continue; // 이 상자만 건너뛴다  }  if (total + w > cap) {    stop = i + 1;    break; // 반복 전체를 끝낸다  }  loaded++;  total += w;}console.log(`${loaded} ${total} ${sent} ${stop}`);
JavaMain.java · 30 行
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());        int cap = Integer.parseInt(st.nextToken());        int limit = Integer.parseInt(st.nextToken());        st = new StringTokenizer(in.readLine());        int loaded = 0, total = 0, sent = 0, stop = 0;        for (int i = 1; i <= n; i++) {            int w = Integer.parseInt(st.nextToken());            if (w > limit) {                sent++;                continue; // 이 상자만 건너뛴다            }            if (total + w > cap) {                stop = i;                break; // 반복 전체를 끝낸다(남은 수는 읽지 않아도 된다)            }            loaded++;            total += w;        }        System.out.println(loaded + " " + total + " " + sent + " " + stop);    }}
C#Main.cs · 30 行
using System;using System.Linq; class Program{    static void Main()    {        int[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();        int n = first[0], cap = first[1], limit = first[2];        int[] boxes = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();        int loaded = 0, total = 0, sent = 0, stop = 0;        for (int i = 0; i < n; i++)        {            int w = boxes[i];            if (w > limit)            {                sent++;                continue; // 이 상자만 건너뛴다            }            if (total + w > cap)            {                stop = i + 1;                break; // 반복 전체를 끝낸다            }            loaded++;            total += w;        }        Console.WriteLine($"{loaded} {total} {sent} {stop}");    }}
C++main.cpp · 25 行
#include <iostream>#include <vector> int main() {    std::ios::sync_with_stdio(false);    int n, cap, limit;    std::cin >> n >> cap >> limit;    std::vector<int> boxes(n);    for (int& w : boxes) std::cin >> w;    int loaded = 0, total = 0, sent = 0, stop = 0;    for (int i = 0; i < n; i++) {        int w = boxes[i];        if (w > limit) {            sent++;            continue;  // 이 상자만 건너뛴다        }        if (total + w > cap) {            stop = i + 1;            break;  // 반복 전체를 끝낸다        }        loaded++;        total += w;    }    std::cout << loaded << " " << total << " " << sent << " " << stop << "\n";}
Cmain.c · 22 行
#include <stdio.h> int main(void) {    int n, cap, limit, w;    int loaded = 0, total = 0, sent = 0, stop = 0;    scanf("%d %d %d", &n, &cap, &limit);    for (int i = 1; i <= n; i++) {        scanf("%d", &w);        if (w > limit) {            sent++;            continue; /* 이 상자만 건너뛴다 */        }        if (total + w > cap) {            stop = i;            break; /* 반복 전체를 끝낸다 */        }        loaded++;        total += w;    }    printf("%d %d %d %d\n", loaded, total, sent, stop);    return 0;}
Craykonmain.cray · 26 行
first = コンソール.数読み();n = first[0];cap = first[1];limit = first[2];boxes = コンソール.数読み();loaded = 0;total = 0;sent = 0;stop = 0;繰り返す (i = 0; i < n; i++){    w = boxes[i];    もし (w > limit)    {        sent++;        次へ; // 이 상자만 건너뛴다    }    もし (total + w > cap)    {        stop = i + 1;        抜ける; // 반복 전체를 끝낸다    }    loaded++;    total += w;}コンソール.書く(loaded + " " + total + " " + sent + " " + stop);