这道题在百炼上的编号是1017
上次Q4提交给师兄后,师兄给出的点评,粘贴到这里,在以后的做题中时刻提醒自己:
“
”
今天这道题是从早晨做到了现在,但却感觉收获很大:
首先,让我知道,任何问题,只要经过努力的思考,总会解决的。
开始的时候想的很简单,很快的写出了一个版本,提交后Runtime error,我猜测是自己定义的数组太大了,就将输入改为动态内存分配,这次没有错,但是Wrong Answer了,静下心来仔细想了下,不可能那么简单,于是就在纸上分析,想到上次提交Q4给师兄的时候,师兄说这些都是写常规的题目,尽量不要看解题思路和答案。我就想一定不能看参考,既然是常规题,认真想肯定会想出来了,用笔在纸上画画真的画出了一种方案,我赶紧将它用程序实现,提交了几次都是Wrong Answer。在提交的过程中,总看见有人Accepted了,就有点小着急,坚持自己的程序,没有发现什么错误。后来ask了师兄,师兄说
在这种情况下,首先是看看文档中的解题思路,看看思路有没有问题。
如果思路没有问题,然后提交几次都出bug,那么要不然找人帮忙看看代码,要不然就可以看看参考程序。
其实参考程序是在你充分思考,反复写代码、调试并提交之后,看的效果最好
对比对比程序,找找问题,看看哪块没有考虑清楚。
这些题的解答结果不重要,重要的是这一套思考问题,用程序解决问题的过程。其实每一道题都可以算作是一个小的项目,都是一个锻炼的过程。每次靠自己的能力做完题目,就类似于靠自己一点点努力完成一个项目或布置得任务。
解决这些题的过程和在公司完成任务的过程类似,所以如果做题做得多的话,在面试时是很占优势的。
就算到了单位,也能很好的完成任务安排。
如果做题这个习惯能坚持到你毕业,那么你就和大牛离得不远了
听了师兄说的,我看了参考的思路分析,看了几句话后就很开心,因为和我之前自己的分析相吻合,这不就是我前几天说的,什么时候我也能一下子就想到这种方法呢,这次虽然不是一下子,但是也是自己想出来的,表扬自己鼓励一下~,那我思路没错,那错在了哪里,再往下看,啊。。好粗心我,竟然在统计剩余的1*1空间处出现遗漏。治学要严谨,coding要细心。知道了自己错在了哪里,就有信心了,很快的补上了遗漏的情况,提交Accepted。
我的code和参考给出的code还有一些差别,在这里都粘贴上来,比较,选择最优,在以后的编程中notice:
my:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int order[6];
int i,j,total;
//动态分配内存
int *p;
p=(int *)malloc(sizeof(int));
//输入订单的数目
for(j=0;;j++){
scanf("%d%d%d%d%d%d",&order[0],&order[1],&order[2],&order[3],&order[4],&order[5]);
total=0;
total=total+order[5]+order[4]+order[3];//处理4*4,5*5,6*6的箱子
int s1=0,s2=0;//s1存储剩余的1*1的空间,s2存储剩余的2*2的空间
s2=5*order[3];
s1=11*order[4];
//处理3*3的箱子,先看需要几个3*3的箱子,不要忘记3*3的剩下的1*1的
if(order[2]%4==0)
{
total=total+order[2]/4;
}else if(order[2]%4==1)
{
total=total+order[2]/4+1;
s2=s2+5;
s1=s1+7;
}else if(order[2]%4==2)
{
total=total+order[2]/4+1;
s2=s2+3;
s1=s1+6;
}else if(order[2]%4==3)
{
total=total+order[2]/4+1;
s2=s2+1;
s1=s1+5;
}
//处理2*2的箱子,注意每一步进行后,剩余的空间的统计
int k=0;
k=s2-order[1];
if(k>=0)
{
s1=s1+k*4;
}else
{
if((-k)%9==0)
{
total=total+(-k)/9;
}else
{
total=total+(-k)/9+1;
s1=s1+(9-(-k)%9)*4;
}
}
//处理1*1的箱子,
int t=0;
t=s1-order[0];
if(t<0)
{
if((-t)%36==0)
{
total=total+(-t)/36;
}else
{
total=total+(-t)/36+1;
}
}
if(total==0)
{
break;
}else{
p[j]=total; //将每次的结果存放到动态数组p[j]中
}
}
for(i=0;i<j;i++)
{
printf("%d\n",p[i]);
}
return 0;
}
参考的:
#include <stdio.h>
int main()
{
int N, a, b, c, d, e, f, y, x ;//N 用来存储需要的箱子数目,y 用来存储2*2 的空位数目
// x 用来存储 1*1 的空位数目。
int u[4]={0, 5, 3, 1};
// 数组u 表示3*3 的产品数目分别是 4 的倍数,4 的倍数+1, 4的倍数+2, 4的倍数+3
// 时,为3*3 的产品打开的新箱子中剩余的2*2 的空位的个数
while(1){
scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &e, &f);
if (a == 0 && b == 0 && c == 0 && d == 0 && e == 0 && f == 0) break;
N = f + e + d + (c + 3) / 4;
// 这里有一个小技巧 - (c+3)/4 正好等于 c 除以4 向上取整的结果, 下同
y = 5 * d + u[c % 4];
if(b > y) N += (b - y + 8 ) / 9;
x = 36 * N - 36 * f - 25 * e - 16 * d - 9 * c - 4 * b;
if(a > x) N += ( a - x + 35 ) / 36;
printf("%d\n", N);
}
return 0;
}
下面给出的参考程序看起来比较简洁,最重要的是简单在了这里:
将我的一长串的判断
if((-t)%36==0)
{ total=total+(-t)/36;
}else {
total=total+(-t)/36+1;
}
用一句((-t)+35)/36就实现了:即实现了(-t)/36向上取整的结果;
将3*3的余数对应的剩余2*2空间的不同的情况放在一个数组里,也是一种巧妙的方法:
int u[4]={0, 5, 3, 1};
但是存在一个问题,没有实现 多行输入 对应 多行输出的条件。
附两张图片,一是今天的时间记录挫折图,柳暗花明又一村:
图二是在纸上画思路的一个草稿: