算法競賽入門經典授課教案第2章 循環結構程序設計_第1頁
算法競賽入門經典授課教案第2章 循環結構程序設計_第2頁
算法競賽入門經典授課教案第2章 循環結構程序設計_第3頁
算法競賽入門經典授課教案第2章 循環結構程序設計_第4頁
算法競賽入門經典授課教案第2章 循環結構程序設計_第5頁
已閱讀5頁,還剩26頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、-作者xxxx-日期xxxx算法競賽入門經典授課教案第2章 循環結構程序設計【精品文檔】第2章 循環結構程序設計【教學內容相關章節】for循環循環結構程序設計 文件操作小結與習題【教學目標】(1)掌握for循環的使用方法;(2)掌握while循環的使用方法;(3)學會使用計算器和累加器;(4)學會用輸出中間結果的方法調試;(5)學會用計時函數測試程序效率;(6)學會用重定向的方式讀寫文件;(7)學會fopen的方式讀寫文件;(8)了解算法競賽對文件讀寫方式和命名的嚴格性;(9)記住變量在賦值之前的值是不確定的;(10)學會使用條件編譯指示構建本地運行環境。【教學要求】掌握for循環的使用方法;

2、掌握while循環的使用方法;掌握幾個常用的文件操作庫函數fopen、fclose、fprintf、fscanf等。【教學內容提要】在有些程序中,需要反復執行某些語句。將n條相同的語句簡單地復制會使程序變得不合理的冗長,因此高級語言中提供了支持程序重復執行某一段程序的循環控制語句。相關的語句有:for、while、do while、break、continue等。既可以從文件中讀取數據, 也可以向文件中寫入數據。讀寫文件之前,首先要打開文件。讀寫文件結束后,要關閉文件。C/C+提供了一系列庫函數,聲明于中,用于進行文件操作。這里介紹其中幾個常用的文件操作庫函數fopen、fclose、fpri

3、ntf、fscanf等。【教學重點、難點】教學重點:(1)掌握for循環的使用方法;(2)掌握while循環的使用方法;(3)掌握文件有關操作;(4)條件編譯。教學難點:(1)掌握for循環的使用方法;(2)掌握while循環的使用方法;【課時安排(共2學時)】 for循環請用for循環實現輸入正整數n,打印1,2,3,10,每個占用一行。程序如下:程序2-1 輸出1,2,3,n的值#include <stdio.h>int main() int i, n; scanf("%d", &n); for(i = 1; i <= n; i+) print

4、f("%dn", i); return 0;提示2-1:for循環的格式:for(初始化;條件;調整) 循環體;提示2-2:盡管for循環反復執行相同的語句,但這些語句每次的執行效果往往不同。提示2-3:編寫程序時,要特別留意“當前行”的跳轉和變量的改變。有了for循環,可以解決一些簡單的問題。例2-1 aabb。輸出所有形如aabb的四位完全平方數(即前兩位數字相等,后兩位數字也相等)。【分析】分支和循環結合在一起時威力特別強大:可以枚舉所有可能的aabb,然后判斷它們是否是完全平方數。注意,a的范圍是19,但b可以是0。主程序如下:for(a = 1; a <=

5、9; a+) for(b = 0; b <= 9; b+) if(aabb是完全平方數) printf("%dn", aabb);注意:(1)上面不是真正的程序,把這樣的代碼稱為偽代碼(psedocode)。(2)上面用到了循環的嵌套:for循環的循環體自身又是一個循環。提示2-4:不拘一格的使用偽代碼來思考和描述算法是一種值得推薦的做法。提示2-5:把偽代碼改寫成代碼時,一般先選擇較為容易的任務來完成。程序2-2 7744問題(1)#include <stdio.h>#include <math.h>int main() int a, b,

6、n; double m; for(a = 1; a <= 9; a+) for(b = 0; b <= 9; b+) n = a*1100 + b*11; m = sqrt(n); if(floor(m+0.5) = m) printf("%dn", n); return 0;說明:函數floor(x)返回x的整數部分,使用floor(m+0.5)=m的原因是浮點數的運算(和函數)有可能存在誤差。提示2-6:浮點運算可能存在誤差。在進行浮點數比較時,應考慮到浮點誤差。對于四位完全平方數的還有另一個思路就是枚舉平方根x,從而避免開平方操作。程序2-3 7744問題

7、(2)#include <stdio.h>int main() int x, n, hi, lo; for(x = 1; ; x+) n = x * x; if(n < 1000) continue; if(n > 9999) break; hi = n / 100; lo = n % 100; if(hi/10 = hi%10 && lo/10 = lo%10) printf("%dn", n); return 0;說明:本程序中用到break和continue語句。break是指直接跳出本層循環,continue是指結束本次循環,

8、但不跳出本層循環,進入下一次循環。2.2 循環結構程序設計例2-2 3n+1問題。猜想:對于任意大于1的自然數,若n為奇數,則將n變為3n+1,否則變為n的一半。經過若干次這樣的變換,一定會使n變為1。例如3105168421。輸入n,輸出變換的次數。n109。樣例輸入:3樣例輸出:7【分析】從3n+1問題可以看出,n也不是“遞增”式的循環,且循環次數也不確定,這種情況非常適合用while循環來實現。程序2-4 3n+1問題#include <stdio.h>int main() int n, count = 0; scanf("%d", &n); wh

9、ile(n > 1) if(n % 2 = 1) n = n*3+1; else n /= 2; count+; printf("%dn", count); return 0;提示2-7:while循環的格式為:“while(條件) 循環體;”。從程序2-4中可得,while循環與for循環可以相互轉化。在本程序中的count+,相當于一個計算器,這個功能在編程中會經常遇到。提示2-8:當需要統計某種事物的個數時,可以用一個變量來充當計算器。提示2-9:不要忘記測試。一個看上去正確的程序可能隱含錯誤。提示2-10:在觀察無法找出錯誤時,可以用“輸出中間結果”的方法查錯

10、。例2-3 階乘之和。輸入n,計算S=1!+2!+3!+n!的末6位(不含前導0)。n106。這里,n!表示前n個正整數之積。樣例輸入:10樣例輸出:37913【分析】用S變量來累加階乘之和。核心算法只有一句話:for(i=1;i<=n;i+) S+=i!。在C語言中沒有階乘運算符,所以還需要一個循環來求i!: for(j=1;j<=i;j+) factorial*=j;。 代碼如下:程序2-5 階乘之和(1)#include <stdio.h>int main() int i, j, n, S = 0; scanf("%d", &n); f

11、or(i = 1; i <= n; i+) int factorial = 1; for(j = 1; j <= i; j+) factorial *= j; S += factorial; printf("%dn", S % 1000000); return 0;注意:每執行一次循環體,都要重新聲明一次累乘器factorial,并初始化為1(因為是乘積,所以初始化為1,要是初始化為0,則循環后的factorial=i!=0)。提示2-11:在循環體開始處定義的變量,每次執行循環體時會重新聲明并初始化。提示2-12:要計算只包含加法、減法和乘法的整數表達式除以正

12、整數n的余數,可以在每步計算之后對n取余,結果不變。程序2-6 階乘之和(2)#include <stdio.h>#include <time.h>int main() const int MOD = 1000000; int i, j, n, S = 0; scanf("%d", &n); for(i = 1; i <= n; i+) int factorial = 1; for(j = 1; j <= i; j+) factorial = (factorial * j % MOD); S = (S + factorial) %

13、 MOD; printf("%dn", S); printf("Time used = %.2lfn", (double)clock() / CLOCKS_PER_SEC); return 0;說明:(1)這個程序真正的特別之處在于計時函數clock()的使用。該函數返回程序目前為止運行的時間,以毫秒為單位。這樣,在程序結束之前調用它,便可獲得整個程序的運行時間。這個時間除以常數CLOCKS_PER_SEC之后得到的值以“秒”為單位。(2)在,其值為1000。VC+6.0中該符號常量定義如下: #define CLOCKS_PER_SEC 1000對于C

14、LOCKS_PER_SEC,它用來表示一秒鐘會有多少個時鐘計時單元,時鐘計時單元的長度為1毫秒,clock()/CLOCKS_PER_SEC就是將毫秒轉化為秒。提示2-13:可以使用time.h和clock()函數獲得程序運行時間。常數CLOCKS_PER_SEC與操作系統有關,請不要直接使用clock()的返回值,而應總是除以CLOCKS_PER_SEC。提示2-14:很多程序的運行時間與規模n存在著近似的簡單關系。可以通過計時函數來發現或驗證這一關系。 本節的兩個例題展示了計數器、累加器的使用和循環結構程序設計中最常見的兩個問題:算術運算溢出和程序效率低下。另外,本節中介紹的兩個工具輸出中

15、間結果和計時函數,都有是相當實用的。2.3 文件操作例2-4 數據統計。輸入一些整數,求出它們的最小值、最大值和平均值(保留3位小數)。輸入保證這些數都是不超過1000的整數。樣例輸入:2 8 3 5 1 7 3 6樣例輸出:【分析】如果是先輸入整數n,然后輸入n個整數,相信能寫出程序。關鍵在于:整數的個數是不確定的。下面給出程序:程序2-7 數據統計(錯誤)#include <stdio.h>int main() int x, n = 0, min, max, s = 0; while(scanf("%d", &x) = 1) s += x; if(x

16、 < min) min = x; if(x > max) max = x; n+; printf("%d %d %.3lfn", min, max, (double)s/n); return 0;說明:(1)scanf函數的返回值是成功輸入的變量個數。當輸入結束時,scanf無法再次讀取x,將返回0。(2)在測試時,輸入2 8 3 5 1 7 3 6,按Enter鍵后,沒有輸出結果,所以此時按Enter鍵并不意味著輸入的結束。提示2-15:在Windows下,輸入完畢后先按Enter鍵,再按Ctrl+Z鍵,最后再按Enter鍵,即可結束鍵入。在Linux下,輸入

17、完畢后按Ctrl+D鍵即可結束輸入。通過提示2-15,輸入可以結束了。但是此程序的運行結果是不確定的。提示2-16:變量在未賦值之前的值是不確定的。特別地,它不一定等于0。解決上面程序的運行結果不對的方法是在變量使用前賦初值。由于min保存的是最小值,它的初值應該是一個很大的數;反過來,max的初值應該是一個很小的數。一種方法是定義一個很大的常數,如INF=1000000000,然后讓max=INF,而min=-INF,而另一種方法是先讀取第一個整數x,然后令max=min=x。另一個好的方法是用文件把輸入數據保存在文件中,輸出數據也保存在文件中。事實上,幾乎所有算法競賽的輸入數據和標準答案都

18、是保存在文件中的。使用文件最簡單的方法是使用輸入輸出重定向,只需要在main函數的入口處加入以下兩條語句:freopen("","r",stdin);freopen("","w",stdout);它將使得scanf從文件input.txt讀入,printf寫入文件output.txt。但是并不是所有算法競賽都允許用程序讀寫文件。甚至有的競賽允許訪問文件,但不允許freopen這樣的重定向方式讀寫文件。請參賽之前仔細閱讀文件讀寫的相關規定。提示2-17:請在比賽之前了解文件讀寫的相關規定:是標準輸入輸出(也稱標準I/

19、O,即直接讀鍵盤、寫屏幕),還是文件輸入輸出?如果是文件輸入輸出,是否禁止用重定向方式訪問文件?多年來,無數選手因文件相關問題丟掉了大量的得分。一個普適的原則是:詳細閱讀比賽規定,并嚴格遵守。例如,如果題目規定程序名稱為test,輸入文件名為test.in,輸出文件名為test.out,就是不要犯以下錯誤。錯誤1:程序存為t1.c(應該改成test.c)。 錯誤2:從input.txt讀取數據(應該從test.in讀取)。 錯誤3:從tset.in讀到數據()。 錯誤4:(擴展名錯誤,應該是test.out)。 錯誤5:數據寫到(不能加路徑,哪怕是相對路徑。文件名應該只有8個字符:test.o

20、ut)。提示2-18:在算法競賽中,選手應嚴格遵守比賽的文件名規定,包括程序文件名和輸入輸出文件名。不要弄錯大小寫,不要拼錯文件名,不要使用絕對路徑或相以路徑。 利用文件是一種好的自我測試方法,但如果比賽要求采用標準輸入輸出,就必須在自我測試完畢之后刪除重定向語句。下面來介紹一種方法可以在本機測試時用文件重定向,但一旦提交到比賽,就自動“刪除”重定向語句。代碼如下:程序2-8 數據統計(重定向版)#define LOCAL#include <stdio.h>#define INF 1000000000int main()#ifdef LOCAL freopen("data

21、.in", "r", stdin); freopen("data.out", "w", stdout);#endif int x, n = 0, min = INF, max = -INF, s = 0; while(scanf("%d", &x) = 1) s += x; if(x < min) min = x; if(x > max) max = x;/* printf("x = %d, min = %d, max = %dn", x, min, max);*/

22、 n+; printf("%d %d %.3lfn", min, max, (double)s/n); return 0;上面是一份典型的比賽代碼,包含了幾個特別的地方:(1)重定向的部分被寫在了#ifdef和#endif中。它的含義是:只有定義了符號LOCAL,才編譯兩條freopen語句。(2)輸出中間結果的printf語句寫在注釋中它在最后版本的程序中不應該出現,但是又舍不得刪除它(萬一發現了新的bug,需要再次用它輸出中間信息)。把它注釋化的好處是:一旦需要的時候,把注釋符去掉即可。上面的代碼在程序首部就定義了符號LOCAL,因此在本機測試時使用重定向方式讀寫文件。

23、如果比賽要求讀寫標準輸入輸出,只需在提交之前刪除#define LOCAL即可。一個更重好的方法是在編譯選項而不是程序里定義這個LOCAL符號,這樣在提交之前不需要修改程序。如果比賽要求用文件輸入輸出,但禁止用重定向的方式,程序如下:程序2-9 數據統計(fopen版)#include <stdio.h>#define INF 1000000000int main() FILE *fin, *fout; fin = fopen("data.in", "rb"); fout = fopen("data.out", "

24、;wb"); int x, n = 0, min = INF, max = -INF, s = 0; while(fscanf(fin, "%d", &x) = 1) s += x; if(x < min) min = x; if(x > max) max = x; n+; fprintf(fout, "%d %d %.3lfn", min, max, (double)s/n); fclose(fin); fclose(fout); return 0;說明:(1)本程序先聲明變量fin和fout,把scanf改成fscanf

25、,第一個參數為fin;把printf改成fprintf,第一個參數為fout,最后執行fclose,關閉兩個文件。(2)重定向和fopen的區別。重定向的方法寫起來簡單、自然,但是不能同時讀寫文件和標準輸入輸出;fopen的寫法稍顯繁瑣,但是靈活性比較大。如果想把fopen版的程序改成讀寫標準輸入輸出,只需賦值fin=stdin;fout=stdout;即可,不要想調用fopen和fclose。2.4 小結與習題2.4.1 輸出技巧首先是輸出技巧。通過對程序2-1進行小小的改動來實現輸出2,4,6,8,2n,每個一行。為了方便,現把程序復復制如下:1 #include <stdio.h&

26、gt;2 int main()3 4 int i, n;5 scanf("%d", &n);6 for(i = 1; i <= n; i+)7 printf("%dn", i);8 return 0;9 任務1:修改第7行,不修改第6行。解答:修改第7行的如下:7 printf("%dn", 2*i);任務2:修改第6行,不修改第7行。解答:修改第6行的如下:6 for(i = 2; i <= 2*n; i+=2)2.4.2 浮點數陷阱“!=”運算符表示“不相等”,則下面的程序的運行結果是什么?#include &

27、lt;stdio.h>int main() double i;for(i=0;i!=10;i+=0.1) printf("%.1lfn",i);return 0;說明:對于i可以達到10.0,但永遠不會與10相等,所以for循環是一個死循環。對于float和dobule類型的數據不能直接用 =和!=來比較大小,即不要測試精確的浮點型數值,需要用精度比較,來測試一個可接受的數值范圍。課本P85頁有這樣的說明。例如,if().2.4.3 64位整數題目:輸入正整數n,統計它的正因子個數。n1012。例如,n=30時,輸出應該為8。【分析】(1)如果i是n的約數,則n/i也

28、是n的約數。所以可以從1 枚舉到。(2)n太大(n1012),超過了int類型的表示范圍(-231231-1,比-2×292×29略寬)。(3)有一種比int更大的類型,稱為long long,它的表示范圍是-263263-1,比-1019-1019略窄。在中(沒有long long數據類型),如果要定義一個long long數據類型的變量a(64位整數)應該定義如下:_int64 a; 輸入輸出的時候用 %I64d,如:scanf("%I64d",&a);printf("%I64d",a); 本題的程序如下:#include

29、 <stdio.h>#include <math.h>int main() _int64 n, /* 注意int64之前是兩個下劃線(_)*/ x,count=0; /* 假設x是n的因子,count為計數器 */scanf("%I64d",&n);for(x=1;x<=(_int64)sqrt(n);x+)if(n%x = 0) count += 2; /* 之所以+2,是因為x和n/x都是n的因子 */ if(n/x = x) count = count-1; printf("%I64dn", count);re

30、turn 0;2.4.4 C+中的輸入輸出“A+B”問題:輸入若干對整數,輸出每對之和。通過經典的“A+B”問題,來用C+語言來研究輸入輸出。(1)方法一#include <cstdio> /功能和C中的stdio.h很接近,但有些許不同using namespace std;int main() int a,b; while(scanf("%d%d", &a, &b)=2) printf("%dn", a+b); return 0;上面的C+程序很像C程序。唯一的區別是原來的stdio.h變成了cstdio,并且多了一條語句

31、using namespace std。這是一個普遍規律要在C+程序中使用C語言頭文件,請去掉擴展名.h,并在最前面加上小字母c。例如,stdio.h在C+中的新名字是cstdio。另外,第一行中以/開頭的是C+特有的“單行注釋”,它和C中的傳統注釋(/*和*/)可以混合使用。(2)方法二(不用記住%d、%lf等惱人的占位符)#include <iostream> /頭文件iostream包含了對輸入輸出流的定義using namespace std;int main() int a,b; while(cin>>a>>b) cout<<a+b&l

32、t;<"n" return 0;下面用輸入輸出文件流來修改方法二,程序如下:#include <fstream>using namespace std;ifstream fin("");ofstream fout("");int main() int a, b; while(fin>>a>>b) fout<<a+b<< "n" return 0;說明:(1)在C+中,將數據從一個對象到另一個對象的流動抽象稱為“流”。文件流是以外存文件為輸入輸出對象的

33、數據流。輸出文件流是從內存流向外存文件的數據,輸入文件流是從外存文件流向內存的數據。每一個文件流都有一個內存緩沖區與之對應。在C+的I/0類庫中定義了幾種文件類,專門用于對磁盤文件的輸入輸出操作,有3個用于文件操作的文件類:ifstream(input file stream)類,它是從istream類派生的。用來支持從磁盤文件的輸入,即從硬盤到內存。可以用下面的方法建立一個輸入文件流對象:ifstream fin("");其中fout為ofstream類(輸出文件流類)的對象。ofstream(output file stream)類,它是從ostream類派生的。用來支

34、持向磁盤文件的輸出,即從內存到硬盤。可以用下面的方法建立一個輸出文件流對象:ofstream fout("");其中fout為ofstream類(輸出文件流類)的對象。fstream類,它是從iostream類派生的,用來支持對磁盤文件的輸入輸出。   (2)文件流與文件的概念的區別在于文件流不是由若干個文件組成的流,文件流本身不是文件,而只是以文件為輸入輸出對象的流,若要對磁盤文件輸入輸出,就必須通過文件流來實現。(3)文件流中的兩個重要的運算符: 析取器(>>)從流中輸入數據。比如本程序中有一個輸入流(fin),fin>&

35、gt;a>>b表示從輸入流中讀取兩個指定類型(即變量a和b的類型)的數據。插入器(<<)向流中輸出數據。比如本程序中有一個輸出流(fout),fout<<a+b<< "n"表示把a+b的值和換行字符("n")輸出到文件輸出流fout中。如果想再次使用cin和cout,是否要逐個把程序中的所有fin和fout替換為cin和cout?不用這么麻煩,只需要把fin和fout的聲明語句去掉,并加上這樣兩行即可:#define fin cin#define fout cout2.4.5 ACM題目中的輸入輸出1ACM

36、題目特點由于ACM競賽題目的輸入數據和輸出數據一般有多組(不定),并且格式多種多樣,所以,如何處理題目的輸入輸出是對大家的一項最基本的要求。這也是困擾初學者的一大問題。經常有剛接觸ACM在線測試系統的同學抱怨:“為什么我在OJ(Online Judge)上連簡單的A+B也通不過?”先給一個競賽樣例:題目名稱:A+B for Input-Output Practice (I)鏈接地址:Time Limit: 1 Seconds    Memory Limit:32768KProblem DescriptionYour task is to Calculat

37、e a + b.Too easy?! Of course! I specially designed the problem for acm beginners. You must have found that some problems have the same titles with this one, yes, all these problems were designed for the same aim. InputThe input will consist of a series of pairs of integers a and b, separated by a sp

38、ace, one pair of integers per line. OutputFor each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input. Sample Input1 510 20Sample Output630初學者很常見的一種寫法:#include <stdio.h>void main() int a,b; scanf(“%d %d”,&a,&a

39、mp;b); printf(“%d”,a+b);但上述代碼提交上述到OJ上不能通過,是什么原因呢?這就是下面需要解決的問題。下面來分類進行介紹。2基本輸入(1)第一類輸入輸入不說明有多少個Input Block,以EOF為結束標志,例如上面的例子。源代碼如下:#include <stdio.h>int main() int a,b; while(scanf("%d %d",&a, &b) != EOF) printf("%dn",a+b); 本類問題的輸入方案為:C語法while(scanf("%d %d"

40、,&a, &b) != EOF)   . C+語法while( cin >> a >> b )    . 說明:scanf函數返回值就是讀出的變量個數,如:scanf("%d %d", &a, &b ); ,如果只有一個整數輸入,返回值是1;如果有兩個整數輸入,返回值是2;如果一個都沒有,則返回值是-1。EOF是一個預定義的常量,等于-1。(2)第二類輸入輸入一開始就會說有n個Input Block,下面接著是輸入n個Input Block。參見:HDOJ_1090(=1090)。源代碼如

41、下:#include <stdio.h>int main() int n,i,a,b; scanf("%d",&n); for(i=0;i<n;i+) scanf("%d %d",&a, &b); printf("%dn",a+b); 本類問題的輸入方案為:C語法scanf("%d",&n); for( i=0 ; i<n ; i+ )     . C+語法cin >> n; for( i=0 ; i<n ; i+ ) &

42、#160;   . (3)第三類輸入輸入不說明有多少個Input Block,但以某個特殊輸入為結束標志。參見:HDOJ_1091(=1091)。源代碼如下:#include <stdio.h> int main() int a,b;while(scanf("%d %d",&a, &b) &&(a!=0 && b!=0) printf("%dn",a+b); 上面程序有什么問題?本類問題的輸入方案為:C語法while(scanf(“%d”,&n) !=EOF &&

43、; n!=0 )   . C+語法while( cin >> n && n != 0 )    . (4)第四類輸入以上幾種情況的組合,可以參照如下網頁,進行上機實驗。=1092=1093=1094(5)第五類輸入輸入一整行的字符串。參見:HDOJ_1048(htt=1048)。本類問題的輸入方案為:C語法char buf20; gets(buf); C+語法如果用string buf;來保存,則用語句getline( cin , buf ); 。如果用char buf 255 ; 來保存,則用語句line( buf, 255 );。說

44、明:scanf("%s%s",str1,str2),在多個字符串之間用一個或多個空格分隔;若使用gets函數,應為gets(str1); gets(str2); 字符串之間用回車符作分隔。通常情況下,接受短字符用scanf函數,接受長字符用gets函數。getchar函數每次只接受一個字符,經常c=getchar()這樣來使用。getline 是一個函數,它可以接受用戶的輸入的字符,直到已達指定個數,或者用戶輸入了特定的字符。它的函數聲明形式(函數原型)如下:istream& getline(char line, int size, char endchar=

45、9;n');不用管它的返回類型,來關心它的三個參數:char line就是一個字符數組,用戶輸入的內容將存入在該數組內。int size表示最多接受幾個字符?用戶超過size的輸入都將不被接受。char endchar表示當用戶輸入endchar指定的字符時,自動結束。默認是回車符。結合后兩個參數,getline可以方便地實現:用戶最多輸入指定個數的字符,如果超過,則僅指定個數的前面字符有效,如果沒有超過,則用戶可以通過回車來結束輸入。char name4;cin.getline(name,4,'n');由于endchar 默認已經是 'n',所以后面那

46、行也可以寫成:cin.getline(name,4);。思考:以下題目屬于哪一類輸入?owproblem.php?pid=1018=10133基本輸出(1)第一類輸出一個Input Block對應一個Output Block,Output Block之間沒有空行。參見:HDOJ_1089(=1089)。本類問題的輸出方案為:C語法   . printf("%dn",ans); C+語法     .cout << ans << endl; (2)第二類輸出一個Input Block對應一個Output Block

47、,每個Output Block之后都有空行。參見:HDOJ_1095(=1095)。源代碼如下:#include <stdio.h>int main() int a,b; while(scanf("%d %d",&a, &b) != EOF) printf("%dnn",a+b); 解決辦法如下:C語法   . printf("%dnn",ans); C+語法    .     cout << ans << endl <

48、;< endl; (3)第三類輸出一個Input Block對應一個Output Block,Output Block之間有空行。參見:HDOJ_1096(=1096)。源代碼如下:#include <stdio.h>int main() int icase,n,i,j,a,sum; scanf("%d",&icase); for(i=0;i<icase;i+) sum=0; scanf("%d",&n); for(j=0;j<n;j+) scanf("%d",&a); sum+=

49、a; if(i<icase-1) printf("%dnn",sum); else printf("%dn",sum); 解決辦法如下:C語法for (k=0;k<count;k+)     while ()               printf("%dn",result);         if(k!=count-1) printf(&qu

50、ot;n"); C+語法類似,輸出語句換一下即可。思考:以下題目屬于哪一類輸出?=1016=10174初學者常見問題(1)編譯錯誤Main函數必須返回int類型(正式比賽);不要在for語句中定義類型;如果_int64不支持,可以用long long代替;使用了漢語的標點符號;itoa不是一個標準的C函數,它能將整數轉換為字符串,是Windows特有的,如果寫跨平臺的程序,使用與ANSI標準兼容的sprintf()函數。int num = 100;char str25;sprintf(str, "%d" , num);另外,拷貝程序容易產生錯誤。(2)C語言處理“

51、混合數據”的問題參見:HDOJ_1170(170)。常見代碼:scanf("%dn",&icase);for (i=0;i<icase;i+) scanf("%c%d%d",&opera,&num1,&num2); (3)printf和cout混用的問題以下的程序輸出什么?#include <stdio.h>#include <iostream.h>int main()int j=0;for(j=0;j<5;j+)cout<<"j="printf(&quo

52、t;%dn",j);return 0;程序輸出為0123j=j=j=j=j=。為什么?因為一個帶緩沖輸出(cout),而一個不帶緩沖輸出(printf)。6OJ上提交代碼后出現的提示在OJ上提交代碼后,會彈出處理頁面,然后單擊處理頁面上的Status(狀態)鏈接,會彈出狀態頁。狀態頁面顯示了Run ID、Submit time、Judge Status(評測狀態)、Problem ID、Language、Run time(時間開銷)、Run memory(內存開銷)、User Name等幾個信息。Judge Status(評測狀態)一般有以下情況。Accepted:恭喜,通過。Pre

53、sentation Error:輸出格式錯誤。Wrong Answer:答案錯誤。Runtime Error:程序運行時發生錯誤,多為數組訪問越界。Time Limit Exceeded:超內存錯誤,程序運行使用的內存超過限制的內存用量。Compile Error:編譯錯誤,源代碼中有語法錯誤。7學習方式(1)通過練習->總結->練習->總結->的過程,使得自己編程水平得到提高;(2)可以在或其它網站上多多練習;(3)可以去杭電ACM論壇或其它ACM論壇上,與別人分享經驗;(4)有問題可以在google、baidu上去搜索。2.4.6 小結現在對本章介紹的循環總結如下:

54、(1)介紹了在編程中的一些經驗,如使用計算器、累加器、以及“當前最小/最大值”這樣的中間變量。使用printf輸出一些關鍵的中間變量能有效地幫助我們了解程序執行過程、發現錯誤。(2)遇到問題需要自己分析和設計,可以先寫出“偽代碼”,然后轉換成程序。偽代碼是為了讓思路更清晰,突出主要矛盾。(3)編寫好程序后,測試顯得相當重要。如前面的例子中幾乎都有陷阱:運算結果溢出、運算時間過長等。對于海量的輸入輸出問題可以通過文件得到緩解。(4)再次強調:編程不是看書看會的,也不是聽課聽會的,而是練會的。2.4.7 上機練習注意,本章的題目需用文件輸入輸出。如果題目代號為abc,那么輸入文件為abc.in,輸

55、出文件為abc.out。如果對文件操作不熟練,請盡量把fopen、freopen兩種方法都嘗試一下。習題2-1 位數(digit)輸入一個不超過109的正整數,輸出它的位數。例如12735的位數是5。請不要使用任何數學函數,只用四則運算和循環語句實現。【分析】采取的策略是不斷地整除10,檢查商是否大于10。程序如下:#include <stdio.h>void main() unsigned long n; /* 無符號的長整型數,占4字節存儲空間 */int digit=1; /* 位數 */scanf("%ld",&n);for (;n>=10

56、;) n=n/10;digit=digit+1;printf("%d",digit);return;習題2-2 水仙花數(daffodil)輸出100999中的所有水仙花數。若3位數ABC=A2+B2+C2,則稱其為水仙花數。例如153=13+53+33,所以153是水仙花數。【分析】采取的策略是窮舉100999之內的所有數據,檢查是否滿足題目的要求。程序如下:#include <stdio.h>void main() int n,a,b,c; /* n的百、十、個位 */for (n=100; n<=999; n=n+1)a = n / 100;b = (n-a*100)/10; /* 也可以寫成 b=(n%100)/10; */c = n % 10;if (n=a*a*a+b*b*b+c*c*c) /* 算術運算的優先級要高于邏輯運算 */printf("%dn",n);return;習題2-3 韓信點兵(hanxi)相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先后以三人一排、五人一排、七人一排地變換隊形,而他每次只掠一眼隊伍的排尾就知道總人數了。輸入3個非負整數a,b,c,表示每種隊形排尾的人數(a<3,b

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論