解题思路

这是一个装箱问题:

  1. 需要将不同尺寸的正方形产品装入 的包裹中
  2. 每种产品的尺寸从 不等
  3. 目标是使用最少的包裹数量

关键思路:

  1. 的产品一个包裹只能放一个
  2. 的产品一个包裹只能放一个,剩余空间可以放 的产品
  3. 的产品一个包裹可以放一个,剩余空间可以放 的产品
  4. 的产品一个包裹可以放四个
  5. 的产品一个包裹可以放九个
  6. 的产品一个包裹可以放

代码

#include <iostream>
using namespace std;

void solve(int a[6]) {
    int ans = 0;
    
    // 处理6*6的箱子
    ans += a[5];
    
    // 处理5*5的箱子
    ans += a[4];
    a[0] = max(0, a[0] - 11 * a[4]);  // 每个5*5箱子可以放11个1*1
    
    // 处理4*4的箱子
    ans += a[3];
    int space4 = 5 * a[3];  // 4*4后的剩余空间可以放2*2和1*1
    int use2 = min(a[1], space4);  // 先放2*2
    a[1] -= use2;
    a[0] = max(0, a[0] - (space4 - use2) * 4);  // 剩余放1*1
    
    // 处理3*3的箱子
    ans += (a[2] + 3) / 4;  // 每4个3*3一个箱子
    int rem3 = (4 - a[2] % 4) % 4;  // 3*3剩余空间
    if(rem3 > 0) {
        int space3 = rem3 * 9;  // 剩余空间
        int use2_3 = min(a[1], space3 / 4);  // 放2*2
        a[1] -= use2_3;
        a[0] = max(0, a[0] - (space3 - use2_3 * 4));  // 剩余放1*1
    }
    
    // 处理2*2的箱子
    ans += (a[1] + 8) / 9;  // 每9个2*2一个箱子
    int rem2 = (9 - a[1] % 9) % 9;  // 2*2剩余空间
    if(rem2 > 0) {
        a[0] = max(0, a[0] - rem2 * 4);  // 剩余放1*1
    }
    
    // 处理1*1的箱子
    ans += (a[0] + 35) / 36;  // 每36个1*1一个箱子
    
    cout << ans << endl;
}

int main() {
    int a[6];
    while(true) {
        bool allZero = true;
        for(int i = 0; i < 6; i++) {
            cin >> a[i];
            if(a[i] != 0) allZero = false;
        }
        if(allZero) break;
        solve(a);
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void solve(int[] a) {
        int ans = 0;
        
        // 处理6*6的箱子
        ans += a[5];
        
        // 处理5*5的箱子
        ans += a[4];
        a[0] = Math.max(0, a[0] - 11 * a[4]);  // 每个5*5箱子可以放11个1*1
        
        // 处理4*4的箱子
        ans += a[3];
        int space4 = 5 * a[3];  // 4*4后的剩余空间可以放2*2和1*1
        int use2 = Math.min(a[1], space4);  // 先放2*2
        a[1] -= use2;
        a[0] = Math.max(0, a[0] - (space4 - use2) * 4);  // 剩余放1*1
        
        // 处理3*3的箱子
        ans += (a[2] + 3) / 4;  // 每4个3*3一个箱子
        int rem3 = (4 - a[2] % 4) % 4;  // 3*3剩余空间
        if(rem3 > 0) {
            int space3 = rem3 * 9;  // 剩余空间
            int use2_3 = Math.min(a[1], space3 / 4);  // 放2*2
            a[1] -= use2_3;
            a[0] = Math.max(0, a[0] - (space3 - use2_3 * 4));  // 剩余放1*1
        }
        
        // 处理2*2的箱子
        ans += (a[1] + 8) / 9;  // 每9个2*2一个箱子
        int rem2 = (9 - a[1] % 9) % 9;  // 2*2剩余空间
        if(rem2 > 0) {
            a[0] = Math.max(0, a[0] - rem2 * 4);  // 剩余放1*1
        }
        
        // 处理1*1的箱子
        ans += (a[0] + 35) / 36;  // 每36个1*1一个箱子
        
        System.out.println(ans);
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(true) {
            int[] a = new int[6];
            boolean allZero = true;
            for(int i = 0; i < 6; i++) {
                a[i] = sc.nextInt();
                if(a[i] != 0) allZero = false;
            }
            if(allZero) break;
            solve(a);
        }
    }
}
def solve(a):
    ans = 0
    
    # 处理6*6的箱子
    ans += a[5]
    
    # 处理5*5的箱子
    ans += a[4]
    a[0] = max(0, a[0] - 11 * a[4])  # 每个5*5箱子可以放11个1*1
    
    # 处理4*4的箱子
    ans += a[3]
    space4 = 5 * a[3]  # 4*4后的剩余空间可以放2*2和1*1
    use2 = min(a[1], space4)  # 先放2*2
    a[1] -= use2
    a[0] = max(0, a[0] - (space4 - use2) * 4)  # 剩余放1*1
    
    # 处理3*3的箱子
    ans += (a[2] + 3) // 4  # 每4个3*3一个箱子
    rem3 = (4 - a[2] % 4) % 4  # 3*3剩余空间
    if rem3 > 0:
        space3 = rem3 * 9  # 剩余空间
        use2_3 = min(a[1], space3 // 4)  # 放2*2
        a[1] -= use2_3
        a[0] = max(0, a[0] - (space3 - use2_3 * 4))  # 剩余放1*1
    
    # 处理2*2的箱子
    ans += (a[1] + 8) // 9  # 每9个2*2一个箱子
    rem2 = (9 - a[1] % 9) % 9  # 2*2剩余空间
    if rem2 > 0:
        a[0] = max(0, a[0] - rem2 * 4)  # 剩余放1*1
    
    # 处理1*1的箱子
    ans += (a[0] + 35) // 36  # 每36个1*1一个箱子
    
    print(ans)

def main():
    while True:
        a = list(map(int, input().split()))
        if all(x == 0 for x in a):
            break
        solve(a)

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:贪心
  • 时间复杂度:,每个测试用例的处理时间是常数
  • 空间复杂度:,只需要固定大小的数组