张三的包裹厂:C++用贪心算法解POJ1017_Packets问题

POJ1017 Packets

题目链接:
POJ1017 Packets

简单理解一下题目:
张三的包裹厂需要将一定数量的盒子放进统一66大小的包裹里打包给客户,所有盒子包括最后的包裹高都为h,也就是说我们只需要考虑横向面积就可以。然后要考虑到不能只按照面积来算,比如66的包裹放了55的盒子之后,66-55=11,尽管33小于11,也放不下,只能放进去1*1的,因为长宽两边都只剩下1宽度的空隙。

简单分析一下题目:
这个题我一开始我的代码一直WA,后来看见Discuss里有个大佬用C语言代码6行就写出来了,属实是让人懵了圈,大佬还写了一个简单的C++代码,但是我一开始看都看不懂,这里贴出他的代码以及我改的代码,我加了注释,然后改了他的变量名,主要是大佬懒得申请新的变量名,就用输入的变量,俺们这种小菜鸟属实是半天才懂,然后那种求余的时候加上一个比求余的数小1的数,我猜目的是在不会影响结果的情况下保证求余的数为正数?(我猜的,嗯)

大佬代码:

#include <iostream>
using namespace std;
int main(){
	int a,s,d,f,g,r;
	while(1){
		cin>>a>>s>>d>>f>>g>>r;
		if(a+s+d+f+g+r==0) break;
		r+=g+f+(d+3)/4;
		a-=11*g;
		s-=5*f;
		if(g=d%4){
			s-=7-2*g;
			a-=8-g;
		}
		if(s>0){
			r+=(s+8)/9;
			a-=4*(9-(s%9));
		} else a+=4*s;
		if(a>0) r+=(a+35)/36;
		cout<<r<<endl;
	}
}

我改的AC代码:

#include<iostream>

using namespace std;
int a[10];

int main()
{
	while (1) {
		cin >> a[1] >> a[2] >> a[3] >> a[4] >> a[5] >> a[6];
		if (a[1] + a[2] + a[3] + a[4] + a[5] + a[6] == 0) break;
		int result = 0;
		result += a[6];
		result += a[5] + a[4] + (a[3] + 3) / 4;//a[5],a[4],a[3]因为比较大,先放起来,a[3]可以4个装一个包裹里
		a[1] -= 11 * a[5];//用11个1*1可以填充一个装有5*5的包裹的空隙
		a[2] -= 5 * a[4];//用5个2*2可以填充一个装有4*4的包裹的空隙
		int temp = 0;
		if (temp = a[3] % 4) {//算出没法装满一个包裹的3*3包裹个数赋值给temp
			a[2] -= 7 - 2 * temp;//算出用几个2*2去填充装有3*3的盒子,并减去
			a[1] -= 8 - temp;//算出用几个1*1去填充剩下的空隙
		}
		if (a[2] > 0) {
			result += (a[2] + 8) / 9;//算出2*2能装满几个盒子
			a[1] -= 4 * (9 - (a[2] % 9));//2*2装不满的用1*1填满
		}
		else a[1] += 4 * a[2];//如果a[2]<=0,也就是说2*2用超支了,就用4个1*1来代替
		if (a[1] > 0)
			result += (a[1] + 35) / 36;//剩余的1*1直接装新包裹
		cout << result << endl;
	}
	return 0;
}

/*
0 0 4 0 0 1
7 5 1 0 0 0
99 10 0 0 3 0
0 0 0 0 0 0
*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值