搬家blog──第一次做ACM OJ

來源:互聯網
上載者:User

  無聊逛百度知道,從高中開始就有的習慣。在中學時代,一般都是幫人做題,比如數學作業、物理作業,當然,還有吹水一般教人學習方法、推薦教輔等。而到了大學,很少人會在百度知道上問高數的題,而且問了還不一定能在不看書的情況做出來(因為高中做題無數,除了競賽題外,數學物理題神馬方法都記得差不多了,要解決百度知道上的非競賽題沒什麼難度)。而又因為大一第一學期就學了C語言,所以便去找些C語言的題目來做做,也當為學習C語言練練手。記得在有人說,要提高C語言,最好的方法就是去百度知道和各個論壇裡去回答C語言的問題,於是我便這麼做了。

 

今天下午,在百度知道亂逛,見有人求助一道ACM

題目出處:****************************************************************************************************************************************

http://acm.uestc.edu.cn/problem.php?pid=1023

GPA計算

 

Time Limit: 1000 ms Memory Limit: 65535 kB
Solved: 630 Tried: 2240

Description

G.P.A.(Grade Point Average)即成績點數與學分的加權平均值。
GPA一般用4分制(4.00 scale)計算,換算方法參見下表:
百分制分數 等級 成績點數
90-100 A 4
80-89 B 3
70-79 C 2
60-69 D 1
60以下 E 0
例如某同學三門課程的學分和成績為:
A課程4個學分,成績92(A)
B課程3個學分,成績75(C)
C課程5個學分,成績80(B)
GPA = (4 * 4 + 2 * 3 + 3 * 5) / (4 + 3 + 5) = 3.08

Input

輸入第一行為整數N(1 <= N <=10),表示有N門課程。
以下N行每行為兩個整數C, S (1 <= C <= 5, 0<= S <= 100)表示該門課程的學分和成績。

Output

輸出僅一個小數g,表示該同學的GPA,結果保留2位小數

Sample Input

3
4 92
3 75
5 80

Sample Output

3.08

Hint

注意: 請嚴格遵守題目所給的輸入輸出格式,不要輸出任何多餘的資訊!
如果使用Java, Java的主類名一定要用Main!

Source

love8909

************************************************************************************************************************************************************

 提問者是用C++做的。我便用C寫了……先用C寫,寫完再看下能不能用C++寫出來。

 

一開始,沒看清題目,沒注意到要把分數轉換為學分,一運行發現,結果是300+肯定錯了。再看看題目,改回來。

然後,就是判斷分數段,我就想先把強制轉換(int)分數/10,小於5的話直接令其等於5,然後用switch,只要一次計算兩次判斷就OK了(一次/10,一次if(),一次switch()判斷),時間上應該比if(){} else if(){} else if(){}……else{}(4次判斷)要快些。

因為最後要保留兩位小數,所以倒數第3行,四捨五入法處理了GPA結果。

於是便提交了下面這份。

 

#include <stdio.h><br />#include <math.h><br />#define N 10 </p><p>int main(void)<br />{<br /> int credit[N], grade[N], GP[N];<br /> int course, count, choice;<br /> int total_grade = 0;<br /> int total_credit = 0;<br /> double GPA; </p><p> scanf("%d", &course);<br /> if (1 <= course && 5 >= course)<br /> {<br /> for (count = 0;count < course; count++)<br /> {<br /> scanf("%d %d", &credit[count], &grade[count]);<br /> choice = (int)(grade[count] / 10);<br /> if (choice < 6)<br /> {<br /> choice = 5;<br /> }<br /> switch(choice)<br /> {<br /> case 5 : GP[count] = 0;break;<br /> case 6 : GP[count] = 1;break;<br /> case 7 : GP[count] = 2;break;<br /> case 8 : GP[count] = 3;break;<br /> case 9 : GP[count] = 4;break;<br /> case 10 : GP[count] = 4;break;<br /> }<br /> }<br /> } </p><p> for (count = 0; count < course; count++)<br /> {<br /> total_grade += credit[count] * GP[count];<br /> total_credit += credit[count];<br /> } </p><p> GPA = (double)total_grade/(double)total_credit; </p><p> GPA = (int)(GPA*pow(10,2) + 0.5)/pow(10,2);<br /> printf("%.2lf", GPA);<br />}

 結果是

149173 icelights 1023 Wrong Answer GCC 1190B   2011-03-0613:28:24 

 

 然後,改吧,改啊改啊改……

#include <stdio.h><br />#include <math.h><br />int main(void)<br />{<br /> int c[10],g[10], GP[10];<br /> int co, n, ;<br /> int tg = 0;<br /> int tc = 0;<br /> double GPA;<br /> scanf("%d", &co);<br /> if (1 <= co && 5 >= co)<br /> {<br /> for (n = 0;n < co; n++)<br /> {<br /> scanf("%d%d", &c[n], &g);<br /> if (0 <= g && 59 >= g)<br /> GP[n] = 0;<br /> else if (60 <= g && 69 >= g)<br /> GP[n] = 1;<br /> else if (70 <= g && 79 >= g)<br /> GP[n] = 2;<br /> else if (80 <= g && 89 >= g)<br /> GP[n] = 3;<br /> else GP[n] = 4;<br /> }<br /> }<br /> for (n = 0; n < co; n++)<br /> {<br /> tg += c[n] * GP[n];<br /> tc += c[n];<br /> }<br /> GPA = (double)tg/(double)tc;<br /> GPA = (int)(GPA*pow(10,2) + 0.5)/pow(10,2);<br /> printf("%.2lf", GPA);<br /> return 0;<br />}

 

這已經提交過4次了,這是第5次,還是錯的……

149191 icelights 1023 WrongAnswer GCC 1046B   2011-03-0614:05:19
149189 icelights 1023 WrongAnswer GCC 978B   2011-03-0614:01:56
149187 icelights 1023 WrongAnswer GCC 1009B   2011-03-0613:58:55
149173 icelights 1023 WrongAnswer GCC 1190B   2011-03-0613:28:24
149172 icelights 1023 WrongAnswer G++ 1190B   2011-03-0613:26:55 //這個就忽略吧,沒看清語言就提交了。

 

然後 ,沒辦法,用C++寫吧。

 

#include <iostream><br />#include <iomanip><br />using namespace std;<br />int main(){<br />int n=0,j=0;<br /> cin>>n;<br />int a[10],b,c[10];<br />for(;j<n;j++){<br /> cin>>a[j]>>b;<br /> if (b>=90 && b<=100)<br /> c[j]=4;<br /> else if(b>=80 && b<=89)<br /> c[j]=3;<br /> else if(b>=70 && b<=79)<br /> c[j]=2;<br /> else if(b>=60 && b<=69)<br /> c[j]=1;<br /> else c[j]=0;<br /> }<br />float p=0,q=0;<br />for(j=0;j<n;j++){<br /> p+=a[j]*c[j];<br /> q+=a[j];<br /> }<br />float GPA=p/q;<br />cout << setprecision(2) << setiosflags(ios::fixed) << GPA;<br />return 0;<br />}

 

結果通過了。
149193 icelights 1023 Accepted G++ 478B 4 ms 1212kB 2011-03-06 14:09:09

另外,不得不佩服一點,對於幾乎相同的內容.cpp比.c檔案小得多了……

於是便在百度知道上回答了……

然後繼續想怎麼用C寫。

編譯通過,但是程式傳回值居然是0x4,也就是說返回錯誤……

編譯器(code::blocks)沒有提示任何error或者warning,我又懶得開VS2008來debug。於是自己找。

結果終於找到,定義了數組g[10];但是使用變數時只用了g.不過搞笑的是居然是運行得到.

改了之後,程式運行結束返回0,但是居然還是wrong answer.

後來,再看,原來,我的一個習慣導致了我的杯具。

題目要求輸入的課程有範圍,結果我按平常習慣,寫帶互動式提醒錯誤修正功能的程式,就多多手手加上了對輸入的判斷。結果就這裡杯具了。

把那個if()去掉後。提交了下面的程式。

 

#include <stdio.h><br />#include <math.h> </p><p>int main(void)<br />{<br /> int c[10], GP[10];<br /> int co, n, g;<br /> int tg = 0;<br /> int tc = 0;<br /> double GPA; </p><p> scanf("%d", &co);<br /> for (n = 0;n < co; n++)<br /> {<br /> scanf("%d%d", &c[n], &g);<br /> if (0 <= g && 59 >= g)<br /> GP[n] = 0;<br /> else if (60 <= g && 69 >= g)<br /> GP[n] = 1;<br /> else if (70 <= g && 79 >= g)<br /> GP[n] = 2;<br /> else if (80 <= g && 89 >= g)<br /> GP[n] = 3;<br /> else GP[n] = 4;<br /> }<br /> for (n = 0; n < co; n++)<br /> {<br /> tg += c[n] * GP[n];<br /> tc += c[n];<br /> }<br /> GPA = (double)tg/(double)tc;<br /> GPA = (int)(GPA*pow(10,2) + 0.5)/pow(10,2);<br /> printf("%.2lf", GPA);<br /> return 0;<br />}

 

結果是:

149200 icelights 1023 Accepted GCC 746B 4 ms 1004kB 2011-03-06 14:29:19

終於通過了。不過.c檔案是746B,而之前寫的C++檔案才478B……杯具啊。

 

後來,用switch()重寫判斷學分等級處,結果如下:

 

#include <stdio.h><br />#include <math.h> </p><p>int main(void)<br />{<br /> int c[10], GP[10];<br /> int co, n, g, ch;<br /> int tg = 0;<br /> int tc = 0;<br /> double GPA; </p><p> scanf("%d", &co);<br /> for (n = 0;n < co; n++)<br /> {<br /> scanf("%d%d", &c[n], &g);<br /> ch = (int)(g / 10);<br /> if (ch < 6)<br /> {<br /> ch = 5;<br /> }<br /> switch(ch)<br /> {<br /> case 5 : GP[n] = 0;break;<br /> case 6 : GP[n] = 1;break;<br /> case 7 : GP[n] = 2;break;<br /> case 8 : GP[n] = 3;break;<br /> case 9 : GP[n] = 4;break;<br /> case 10 : GP[n] = 4;break;<br /> }<br /> }<br /> for (n = 0; n < co; n++)<br /> {<br /> tg += c[n] * GP[n];<br /> tc += c[n];<br /> }<br /> GPA = (double)tg/(double)tc;<br /> GPA = (int)(GPA*pow(10,2) + 0.5)/pow(10,2);<br /> printf("%.2lf", GPA);<br /> return 0;<br />}

 

結果是:
149216 icelights 1023 Accepted GCC 907B 4 ms 1004kB 2011-03-06 15:53:56

 

不過檔案體積比起用多重if()判斷要大得多……907B啊

 

感想:

 

ACM真的就是考演算法的比賽,和一般寫的互動程式不同,不要求驗證輸入,提示輸入錯誤。它假定所以輸入都是符合規範的,因此做題重點在於演算法的設計而不是使用者介面的友好(當然我承認,C寫的黑底白字的框框也不會產生什麼友好的介面,至少是在這個windows流行的時代)。

這讓我想起中學做數學、物理等理科題時,不斷地被強調格式、書寫,這或者就是指使用者介面的友好吧。而算式本身則是演算法吧。

中學做題我很討厭XX格式,而到了大學,寫程式時,我卻反而很注重使用者介面的友好,不知為什麼會有這樣的變化呢……

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.