這道題在百鍊上的編號是1017
上次Q4提交給師兄後,師兄給出的點評,粘貼到這裡,在以後的做題中時刻提醒自己:
“
我發現你做題時現在存在幾個問題1.參考標準答案過多,要盡量爭取自己打出來,這是這些題都是常規題,只是你的電腦思維鍛煉的還比較少,而這種思維是後面項目編程所必需的。2.如果實在答不出來了,可以看看標準答案,但是不要看標準程式。只能看“解題思路”,絕對不能看“參考程式”。從解題思維那裡學到了如何解決問題,但“如何?”也是一個需要鍛煉的能力。 “參考程式”在你沒有"Accept"之前,是決不允許看的!3.寫一寫程式,然後再看看電腦演算法與資料結構類似的書,對提高編程思維有好處。這些書也不著急一定看完,但是一定要堅持看,堅持看一本就足夠了。
我原來也像你一樣用功,但是發現學的並不好,後來我才知道原因:“身體的勤奮不是真正的勤奮,而是頭腦上的勤奮。身體上再勤奮,卻不思考,只知道蠻幹,也算是一種懶惰”
”
今天這道題是從早晨做到了現在,但卻感覺收穫很大:
首先,讓我知道,任何問題,只要經過努力的思考,總會解決的。
開始的時候想的很簡單,很快的寫出了一個版本,提交後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};
但是存在一個問題,沒有實現 多行輸入 對應 多行輸出的條件。
附兩張圖片,一是今天的時間記錄挫折圖,柳暗花明又一村:
圖二是在紙上畫思路的一個草稿: