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