输入包含多组数据。
每组数据一行,包含六个自然数,分别表示1×1至6×6这六种产品的数量。
对应每组输入,输出最小的包裹数。
0 0 4 0 0 1 7 5 1 0 0 0
2 1
#include "iostream" //CPP
using namespace std; //CPP
int s1,s2,s3,s4,s5,s6,o2,o1,z;
int main(void){
while(cin>>s1>>s2>>s3>>s4>>s5>>s6){
z = s4 + s5 + s6; //z是一共需要的箱子数。先算4*4 5*5 6*6需要的箱子数(一箱只能装一个)
z += (s3%4>0)? (s3/4+1) : (s3/4);//z加上 3*3需要的箱子数
o2 = (s3%4>0)? (s4*5+(7-2*(s3%4))) : (s4*5);//剩下的2*2空间。注:3*3一箱装不满的有s3%4个,剩下空间2*2还可以装7-2(s3%4)个(s3%4为0则这项去掉),加上4*4的,共还剩s4*5+(7-2*(s3%4))个2*2空间
if(s2 > o2){ //剩下的装满2*2后溢出
z += ((s2-o2)%9>0)? ((s2-o2)/9+1) : ((s2-o2)/9);//z加上 多出来的2*2需要的箱子数
if((s2-o2)%9>0) o1 = (s3%4>0)? (s5*11 +(8-s3%4)+(36-4*((s2-o2)%9))) : (s5*11+(36-4*((s2-o2)%9)));//剩下的1*1空间。注:3*3一箱装不满的有s3%4个,剩下空间装满2*2后还可以塞(8-s3%4)个1*1(s3%4为0则这项去掉)。2*2装不满的有(s2-o2)%9,还剩36-4*((s2-o2)%9)个1*1空间((s2-o2)%9为0则这项去掉)。
if((s2-o2)%9==0) o1 = (s3%4>0)? (s5*11+(8-s3%4)) : (s5*11);//剩下的1*1空间(也是要分 多的2*2是否被整除即(s2-o2)%9为0与否 的情况讨论,和条件运算符一个意思)
if(s1 > o1) z += ((s1-o1)%36>0)? ((s1-o1)/36+1) : ((s1-o1)/36);//z加上 多出来的1*1需要的箱子数
}
else{//剩下的刚好装2*2甚至有富余
o1 = (s3%4>0)? (s5*11+(8-s3%4)+(o2-s2)*4) : (s5*11+(o2-s2)*4);//剩下的1*1空间。2*2若刚好装满还有s5*11+(8-s3%4)个1*1空间(s3%4为0则去掉(8-s3%4)),若少几个2*2则多几个4倍的1*1空间
if(s1 > o1) z += ((s1-o1)%36>0)? ((s1-o1)/36+1) : ((s1-o1)/36);//z加上 多出来的1*1需要的箱子数
}
cout<<z<<endl;
}
return 0;
}
通过
贪心法处理
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <exception>
#include <iomanip>
#include <memory>
#include <sstream>
#define INF 1000000
using namespace std;
int main(int argc, char** argv)
{
//freopen("in.txt", "r", stdin);
int w1, w2, w3, w4, w5, w6;
while (cin >> w1 >> w2 >> w3 >> w4 >> w5 >> w6)
{
int leftRegion = 0;
int res = w6;
res += w5;
leftRegion = w5 * 11;
w1 = max(0,w1 - w5 * 11);
res += w4;
leftRegion = 20 * w4;
if (leftRegion <= w2 * 4){ w2 -= leftRegion / 4; leftRegion = 0; }
else {leftRegion -= w2 * 4; w2 = 0; }
if (leftRegion > 0) w1 = max(0, w1 - leftRegion);
res += w3 / 4;
w3 %= 4;
if (w3 > 0)
{
++res;
leftRegion = (4 - w3) * 9;
if (leftRegion <= w2 * 4){ w2 -= leftRegion / 4; leftRegion = 0; }
else { leftRegion -= w2 * 4; w2 = 0; }
if (leftRegion > 0) w1 = max(0, w1 - leftRegion);
}
res += w2 / 9;
w2 %= 9;
if (w2 > 0)
{
++res;
leftRegion = (9 - w2) * 4;
w1 = max(0, w1 - leftRegion);
}
res += w1 / 36;
if (w1 % 36 > 0) ++res;
cout << res << endl;
}
return 0;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line = br.readLine()) != null){
if(line.equals("0 0 0 0 0 0")) break;
String[] params = line.split(" ");
int[] size = new int[7];
for(int i = 0; i < 6; i++) size[i + 1] = Integer.parseInt(params[i]);
// 尺寸为6*6,5*5和4*4的产品必须要占一个包裹,一个包裹最多能装4个尺寸为3*3的产品
int count = size[6] + size[5] + size[4] + (size[3] + 3)/4;
size[3] %= 4; // 剩下3*3尺寸的产品数
// 5*5产品占的包裹中只能再塞1*1的产品
int remain1 = Math.max(0, size[1] - size[5]*11); // 装完5*5产品所在的包裹后,剩下的1*1产品
// 4*4产品占的包裹中能再塞1*1和2*2的产品
int remain2 = 0; // 装完4*4产品所占包裹后,剩下的2*2产品
int remainSpace = 0; // 剩余空间
if(size[2] > size[4]*5){
remain2 = size[2] - size[4]*5; // 放了一个4*4产品之后还能放5个2*2产品
}else{
// 装完2*2产品看看4*4产品占的包裹还剩下多少空间
remainSpace = size[4]*20 - size[2]*4;
// 有多余的空间就用来放1*1的产品
remain1 = Math.max(0, remain1 - remainSpace);
}
// 3*3产品占的包裹中能再塞1*1和2*2的产品,分为三种情况
if(size[3] == 1){
if(remain2 > 5){
remain2 -= 5; // 3*3产品所占包裹最多还能装5个2*2产品
remain1 = Math.max(0, remain1 - 7); // 余下的空间还可以继续装1*1产品
}else{
// 装完2*2产品看看3*3产品占的包裹还剩下多少空间
remainSpace += 27 - remain2*4;
// 有多余的空间就用来放1*1的产品
remain1 = Math.max(0, remain1 - remainSpace);
remain2 = 0;
}
}
if(size[3] == 2){
if(remain2 > 3){
remain2 -= 3;
remain1 = Math.max(0, remain1 - 6);
}else{
remainSpace += 18 - remain2*4;
remain1 = Math.max(0, remain1 - remainSpace);
remain2 = 0;
}
}
if(size[3] == 3){
if(remain2 >= 1){
remain2 -= 1;
remain1 = Math.max(0, remain1 - 5);
}else{
remainSpace += 9;
remain1 = Math.max(0, remain1 - remainSpace);
remain2 = 0;
}
}
// 最后如果还剩下1*1和2*2的产品,就开新的包裹
count += (remain1 + 4*remain2 + 35)/36;
System.out.println(count);
}
}
} # 假设1x1到6x6的产品各自有a,b,c,d,e,f个
# 对于6x6的产品,一个箱子最多只能装入1个,无剩余空间
# 因此,所有6x6的产品总共需要的箱子数=1x1的产品数f
# 对于5x5的产品,一个箱子最多只能装入1个,剩余空间可以装入11个1x1的产品
# 因此,所有5x5的产品总共需要的箱子数=5x5的产品数e
# 对于4x4的产品,一个箱子最多只能装入1个,剩余空间可以装入5个2x2的产品
# 因此,所有4x4的产品总共需要的箱子数=4x4的产品数d
# 对于3x3的产品,一个箱子可以装1个、2个、3个或者4个
# (1)如果装入1个3x3的产品,那么剩余空间可以装入5个2x2的产品+7个1x1的产品
# (2)如果装入2个3x3的产品,那么剩余空间可以装入3个2x2的产品+6个1x1的产品
# (3)如果装入3个3x3的产品,那么剩余空间可以装入1个2x2的产品+5个1x1的产品
# (4)如果装入4个3x3的产品,无剩余空间
# 因此,所有3x3的产品总共需要的箱子数=(3x3的产品数c+3)//4
# 对于2x2的产品,一个箱子可以装9个,无剩余空间
# 同时注意到:
# 装有4x4产品的箱子还可以装入5个2x2的产品,
# 装有3x3产品的箱子,也还可以装入若干个2x2的产品,对应关系如下:
# 装入1个3x3的产品,剩余空间还可以装入5个2x2的产品
# 装入2个3x3的产品,剩余空间还可以装入3个2x2的产品
# 装入3个3x3的产品,剩余空间还可以装入1个2x2的产品
# 本着使用最少箱子数的原则,有2x2产品的空余位置则优先填补到空余位置
# 因此,如果所有2x2产品总共需要的箱子数小于当前空余位置数,则无需为2x2的产品开辟新的箱子,否则,计算没装完的2x2的产品数,开辟新的箱子
# 至此,对于3x3,4x4、5x5和6x6的产品,总共需要的箱子数=`(c+3)//4+d+e+f`
# 对于2x2的产品,一个4x4的产品占用一个箱子,剩余位置可以装入5个2x2的产品
# 剩余3x3产品的个数与剩余3x3产品所在箱子剩余位置可以装入的2x2产品的数量对应关系为:{4:0, 1:5, 2:3, 3:1},
# 用数组表示为arr=[0,5,3,1],数组下表是剩余3x3产品数,数组元素是对应空余位置能装入的2x2的产品数
# 因此,对于2x2的产品,如果2x2产品数小于剩余空闲位置能够容纳的2x2产品数=`d*5+arr[c%4]`,那么无需额外开辟新的箱子
# 反之,计算多出来无法装入的2x2产品数,这些多出来的2x2产品(假设有num个)总共需要的箱子数=(num+8)//9
# 最后,对于1x1的产品,将全部空间减去2x2到6x6产品所占用的空间need1num=box_num*36-(f*36+e*25+d*16+c*9+b*4),看看剩余空间能不能装入全部的1x1产品
# 如果能,那么无需开辟新的箱子,否则,多出来num=a-need1num个箱子,那么总共需要新开辟的箱子数=(num+35)//36
# 注意,在计算2x2产品需要的箱子数时,已经包含了将2x2产品装入到4x4和3x3产品所在箱子剩余空闲位置这一事实
def box(a,b,c,d,e,f):
# 3x3到6x6的产品需要的箱子数
box=(c+3)//4+d+e+f
arr=[0,5,3,1]#4,1,2,3个3x3产品对应剩余位置能够装入的2x2产品数
# 3x3到6x6的产品(其实就是4x4和3x3的)需要的箱子剩余未知能够容纳的2x2产品数
need2num=d*5+arr[c%4]
# 2x2产品需要的箱子数
if need2num<b:
box+=((b-need2num)+8)//9
# 1x2到6x6的产品(其实就是5x5,4x4,3x3和2x2的)需要的箱子剩余未知能够容纳的1x1产品数
need1num=box*36-(f*36+e*25+d*16+c*9+b*4)
# 1x1产品需要的箱子数
if need1num<a:
box+=((a-need1num)+35)//36
return box
while True:
try:
a,b,c,d,e,f=list(map(int,input().split(' ')))
res=box(a,b,c,d,e,f)
print(res)
except:
break is_empty = [0] * 6 while True: try: parcels = list(map(int, input().split())) if parcels == is_empty: print(0) continue sealed, parcels[2] = divmod(parcels[2], 4) sealed += sum(parcels[3:]) parcels[0] -= parcels[4] * 11 can_pack = [0, parcels[3] * 5] if parcels[2] > 0: sealed += 1 tmp = 9 - 2*(parcels[2] + 1) can_pack[1] += tmp can_pack[0] = 36 - parcels[2]*9 - tmp*4 parcels[1] -= can_pack[1] parcels[0] -= can_pack[0] if parcels[1] <= 0: parcels[0] += parcels[1] * 4 if parcels[0] <= 0: print(sealed) continue tmp = int(parcels[1]//9) parcels[1] = parcels[1] - tmp*9 sealed += tmp if parcels[1] > 0: sealed += 1 parcels[0] -= 36 - parcels[1]*4 if parcels[0] > 0: tmp = parcels[0] % 36 sealed += parcels[0]//36 if tmp == 0 else parcels[0]//36 + 1 print(sealed) except: break
#include<iostream>
using namespace std;
int f(int a[6])
{ int s1=0,s2=0;//s1 s2分别代表剩下可以装1*1和2*2的最大值
int num=0;//用于存放返回值
// 6*6 5*5 4*4的情况
if(a[5]>0) //6*6
num+=a[5];
if(a[4]>0) //5*5
{num+=a[4];
s1+=a[4]*11;
}
if(a[3]>0) //4*4
{num+=a[3];
s1+=a[3]*20;
s2+=a[3]*5;
}
// 3*3
if(a[2]>0)
{ num+=(a[2]-1)/4+1;
int j=a[2]%4;
if(j>0)
{s1+=36-j*9;
s2+=7-2*j;}
}
//2*2
if(a[1]>0)
{if(a[1]<=s2)
s1=s1-4*a[1] ;
else if(a[1]>s2)
{ num+=((a[1]-s2)-1)/9+1; //用新的去放2*2
int k=(a[1]-s2)%9;
if(k>0)
{ s1+=36-k*4;
}
s1=s1-4*s2;
}
}
//1*1
if(a[0]>0)
{if(a[0]<=s1)
return num;
else
{num+=((a[0]-s1)-1)/36+1;
}
}
return num;
}
int main()
{ int a[6];//用于存放输入
int i=0;
while(cin>>a[i++])
{
if(i==6)
{ cout<<f(a)<<endl;//输出结果
i=0;}
}
return 0;
}
Scanner sc = new Scanner(System.in);
int[] a = new int[6];