工厂生产的产品包装在相同高度h,尺寸为1 * 1,2 * 2,3 * 3,4 * 4,5 * 5,6 * 6的方形包装中。 这些产品始终以与产品高度相同的尺寸为6 * 6的包裹交付给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由你来设计。
输入文件包括几行,每一行代表一个订单。每个订单里的一行包括六个整数,中间用空格隔开,分别为 1*1 至 6*6 这六种产品的数量。输入文件将以 6 个 0 组成的一行结尾。
除了输入的最后一行 6 个 0 以外,输入文件里每一行对应着输出文件的一行,每一行输出一个整数代表对应的订单所需的最小包裹数。
0 0 4 0 0 1 7 5 1 0 0 0 0 0 0 0 0 0
2 1
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { int[] arr = new int[7]; boolean flag = true; for (int i=1; i<=6; i++) { arr[i] = sc.nextInt(); if (arr[i] != 0) { flag = false; } } if (flag) { return; } int ans = 0; ans = ans + arr[6] + arr[5] + arr[4] + (arr[3] + 3) / 4; int[] two_in_three = {0, 5, 3, 1}; ans += Math.max(0, ((arr[2] - arr[4] * 5 - two_in_three[arr[3] % 4] + 8) / 9)); ans += Math.max(0, ((arr[1] - (36 * ans - 36 * arr[6] - 25 * arr[5] - 16 * arr[4] - 9 * arr[3] - 4 * arr[2] + 35)) / 36)); System.out.println(ans); } } }
num[0] = max(0,num[0]-9*num[-2])3. 对于 4*4 的,有些复杂。先统计数目,再拿 2*2 的凑,如果出现凑不够的情况,就在从 1*1 里面选。对应代码:
num[0] = max(0,num[0]-4*(5*num[3]-num[1]))4. 只剩下3*3,2*2和1*1的包裹了,此时不必讨论,直接算余下的包裹总面积,除以 6*6 即可。向上取整就行。
import sys import math def solve(num): res =sum(num[-3:]) num[0] = max(0,num[0]-9*num[-2]) if num[1]<5*num[3]: num[0] = max(0,num[0]-4*(5*num[3]-num[1])) num[1]=0 else: num[1] -= 5*num[3] k = num[0]+4*num[1]+9*num[2] res += int(math.ceil(k/36.0)) return res if __name__=='__main__': for line in sys.stdin.readlines(): temp = list(map(int,line.split())) if temp == [0]*len(temp): break print(solve(temp))
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); } } }
#include <bits/stdc++.h> using namespace std; int main(){ int a[6]; while(true){ bool flag = true; for(int i=0;i<6;i++){ scanf("%d", &a[i]); if(a[i]!=0) flag = false; } if(flag) return 0; int s = 0; for(int i=3;i<6;i++) s += a[i]; a[0] = max(a[0]-9*a[4], 0); if(a[1] < 5*a[3]){ a[0] = max(a[0]-4*(5*a[3]-a[1]), 0); a[1] = 0; }else a[1] -= 5*a[3]; s += int(ceil((a[0]+4*a[1]+9*a[2])/36.0)); printf("%d\n", s); } return 0; }
#include <stdio.h> int a,b,c,d,e; int main() { int sum; while(scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&sum)!=EOF && a+b+c+d+e+sum) { if(e) { sum += e; if(a>e*11) a -= e * 11; else a = 0; } if(d) { sum += d; if(b>e*5) b -= e * 5; else { b = 0; if(a>((e*5-b)<<2)) a -= (e * 5 - b) << 2; else a = 0; } } if(c) { sum += (c >> 2); if(c%4) { sum++; if(c%4==1) { if(b>=5) { b -= 5; if(a>7) a -= 7; else a = 0; } else { if(a>((5-b)<<2)+7) a -= ((5 - b) << 2) + 7; else a = 0; } } else if(c%4==2) { if(b>=3) { b -= 3; if(a>6) a -= 6; else a = 0; } else { if(a>((3-b)<<2)+6) a -= ((3 - b) << 2) + 6; else a = 0; } } else { if(b) { b--; if(a>5) a -= 5; else a = 0; } else { if(a>9) a -= 9; else a = 0; } } } } if(b) { sum += b / 9; if(b%9) { sum++; if(a>36-((b%9)<<2)) a -= 36 - ((b % 9) << 2); else a = 0; } } if(a) { sum += a / 36; if(a%36) sum++; } printf("%d\n",sum); } return 0; }
//先填大的,再填小的 #include<iostream> using namespace std; int main() { int input[7]; while(cin >> input[1] >> input[2] >> input[3] >> input[4] >> input[5] >> input[6]) { int num = 0;int one_num = 0;int two_num = 0; if(!input[1]&&!input[2]&&!input[3]&&!input[4]&&!input[5]&&!input[6]) return 0; num = input[6] + input[5] + input[4];//先装size为6/5/4的,一个只能装一箱。会有剩余空间,剩余尽量用2的装 one_num = 11 * input[5]; two_num = 5 * input[4]; num += (input[3] + 3)/4; //装size为3箱子数目 int tem = input[3] % 4; //最后一个箱子中有几个size大小为3的,根据不同的情况判断填2还是1 if(tem == 1){two_num += 5;one_num += 7;} else if(tem == 2){two_num += 3;one_num += 6;} else if(tem == 3){two_num += 1;one_num += 5;} if(two_num > input[2]) one_num += (two_num-input[2])*4; //剩余空间大于2的数目,剩下的用1填 else if(two_num < input[2]){ //剩余空间小于2的数目,最后会剩下一箱里有若干2的 num += (input[2] - two_num + 8)/9; one_num += (9 - (input[2] - two_num)%9)*4; } if(one_num < input[1]) num += (input[1] - one_num)/36; cout << num << endl; } }
#include<iostream> #include<math.h> using namespace std; int main() { int arr[7]; while(cin>>arr[1]>>arr[2]>>arr[3]>>arr[4]>>arr[5]>>arr[6]) { if(((!arr[1]&&!arr[2])&&(!arr[3]&&!arr[4]))&&(!arr[5]&&!arr[6])) return 0;//判断输入结束 int x; int can1,can2,would1,would2; //分别存放可以容纳的细碎的小块和实际输出 can2=5*arr[4]+(4-arr[3]%4); if(arr[2]>can2) { would2=(arr[2]-can2)/9+1; can1=11*arr[5]+(4-arr[3]%4)*5+(9-(arr[2]-can2)%9)*4; } else { would2=0; can1=11*arr[5]+20*arr[4]+(4-arr[3]%4)*9-4*arr[2]; } if(arr[1]>can1) { would1=(arr[1]-can1)/36+1; } else { would1=0; } x=arr[6]+arr[5]+arr[4]+ceil(double(arr[3])/4)+would2+would1; cout<<x<<endl; } }简直是完全的数学推导,分情况讨论
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @author wylu */ 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) { String[] strs = line.split(" "); int[] counts = new int[strs.length]; boolean flag = true; for (int i = 0; i < strs.length; i++) { counts[i] = Integer.parseInt(strs[i]); if (flag && counts[i] != 0) flag = false; } if (flag) return; // 6 * 6 int res = counts[5]; // 5 * 5 res += counts[4]; counts[0] -= counts[4] * 11; // 4 * 4 res += counts[3]; int fillTwo = counts[3] * 5; counts[1] -= (fillTwo >= counts[1]) ? counts[1] : fillTwo; counts[0] -= (fillTwo >= counts[1]) ? (fillTwo - counts[1]) : 0; // 3 * 3 int rmd = counts[2] % 4; res += (counts[2] / 4 + (rmd == 0 ? 0 : 1)); int[] two = {0, 5, 3, 1}, one = {0, 27, 18, 9}; if (rmd > 0) { counts[1] -= (two[rmd] >= counts[1]) ? counts[1] : two[rmd]; counts[0] -= (two[rmd] >= counts[1]) ? (one[rmd] - counts[1] * 4) : (8 - rmd); } // 2 * 2 res += (counts[1] / 9 + (counts[1] % 9 == 0 ? 0 : 1)); if (counts[1] % 9 > 0) counts[0] -= (36 - counts[1] % 9 * 4); // 1 * 1 if (counts[1] > 0) res += (counts[0] / 36 + (counts[0] % 36 == 0 ? 0 : 1)); System.out.println(res); } } }
#include <iostream> using namespace std; int main(int argc, char *argv[]) { int i, size1, size2, size3, size4, size5, size6, need; while(cin >> size1 >> size2 >> size3 >> size4 >> size5 >> size6) { if(size1 == 0 && size2 == 0 && size3 == 0 && size4 == 0 && size5 == 0 && size6 == 0) { break; } /* 优先装规格大的包装,可得到最少的包裹数目 */ need = size6; // 6*6的包装不可能和别的拼 need += size5; size1 -= size5 * 11; // 5*5的包装只能和1*1的包装拼 need += size4; size2 -= size4 * 10; //4*4的包装优先和2*2的包装拼 if(size2 < 0) //如果2*2的包装不足够和4*4的拼满,则1*1的和4*4的拼 { size1 += size2; } need += size3 / 4; // 优先把4个3*3的放到一个包裹,如果有多余的3*3,优先和2*2拼,再和1*1拼 if(size3 % 4 == 1) { need++; size1 -= 3; size2 -= 12; } else if(size3 % 4 == 2) { need++; size2 -= 9; } else if(size3 % 4 == 3) { need++; size1 -= 3; size2 -= 3; } /* 经过前面的操作,3*3,4*4,5*5,6*6的肯定没有剩余,接下来看看2*2和1*1的有没有剩余 */ if(size2 > 0) // 如果2*2的还有剩余 { need += size2 / 18; if(size2 % 18 != 0) { need++; size1 -= (36 - (size2 % 18) * 2); //多出来的2*2还可以和这些个1*1的拼 } } if(size1 > 0) // 如果1*1的还有剩余 { need += size1 / 36; if(size1 % 36 != 0) { need++; } } cout << need << endl; } return 0; }
#include <stdio.h> int main() { int box[7], cnt, emptyFor1, emptyFor2; while (~scanf("%d%d%d%d%d%d", &box[1], &box[2], &box[3], &box[4], &box[5], &box[6])) { if (!(box[1] || box[2] || box[3] || box[4] || box[5] || box[6])) break; cnt = box[6] + box[5] + box[4] + (box[3]+3) / 4; emptyFor2 = 5 * box[4]; emptyFor1 = 11 * box[5]; switch (box[3] % 4) { case 1: emptyFor2 += 5; emptyFor1 += 7; break; case 2: emptyFor2 += 3; emptyFor1 += 6; break; case 3: emptyFor2 += 1; emptyFor1 += 5; break; default: break; } if (emptyFor2 >= box[2]) { box[2] = 0; emptyFor1 += (emptyFor2-box[2]) * 4; } else { box[2] -= emptyFor2; } cnt += (box[2]+8)/9; emptyFor1 += 4*(box[2]%9); cnt += emptyFor1>=box[1] ? 0 : (box[1]-emptyFor1+35)/36; printf("%d\n", cnt); } return 0; }