2017北一女中 資訊能力競賽 暑期培訓營 Anny@T.F.G.

Slides:



Advertisements
Similar presentations
CSIM, PU C Language Introduction to the C Programming Language 重覆敘述 (for,while,break,continue) 適合重複性的計算或判斷.
Advertisements

电子成绩单项目实现.
Loops.
補充: Input from a text file
专题研讨课二: 数组在解决复杂问题中的作用
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
C语言程序设计 第八章 函数.
C语言程序设计 第十二章 位运算.
第一章 程序设计入门.
高级语言程序设计 主讲人:陈玉华.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
第3章 顺序结构程序设计 本章要点: 格式化输出函数──printf() 格式输入函数——scanf() 字符输出函数——putchar()
东北林业大学 陈宇 ACM程序设计 东北林业大学 陈宇
C++程序设计 第二讲 清华大学软件学院.
第四章 函数和递归.
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
C程序设计.
第五章 选择结构程序设计 一、关系运算符和表达式 1、关系运算符 在程序中经常需要比较两个量的大小关系, 以决定程序下一步
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
Chap 2 用C语言编写程序 2.1 在屏幕上显示 Hello World! 2.2 求华氏温度 100°F 对应的摄氏温度
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
Function.
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
Introduction to the C Programming Language
作弊是否很有诱惑性? 上堂课已经讲了 作业不一定在两个小时里都能完成 答疑没有一个人? 作弊是有记录的 心理系很多同学集体作弊,让人震惊
第二章 顺序结构 1 数据类型和标识符、常量与变量 2 运算符和表达式 3 简单的输入输出 4 程序举例.
第四章 C 语言中的输入和输出.
C语言 程序设计基础与试验 刘新国、2012年秋.
THE C PROGRAMMING LANGUAGE
本章中將會更詳細地考慮有關重複的概念,並且會 介紹for和do…while等兩種用來控制重複的敘述 式。 也將會介紹switch多重選擇敘述式。 我們會討論直接和迅速離開某種控制敘述式的 break敘述式,以及用來跳過重複敘述式本體剩餘 部份的continue敘述式。 本章會討論用來組合控制條件的邏輯運算子,最後.
2017北一女中 資訊能力競賽 暑期培訓營
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
第三章 顺序结构程序设计 主讲教师 贾月乐 电话:
第3章 顺序结构程序设计 为了让计算机处理各种数据,首先就应该把源数据输入到计算机中;计算机处理结束后,再将目标数据信息以人能够识别的方式输出。C语言中的输入输出操作,是由C语言编译系统提供的库函数来实现。 3.1 格式化输出——printf()函数 3.2 格式化输入——scanf()函数.
第5讲 结构化程序设计(Part II) 周水庚 2018年10月11日.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
第4章 顺序程序设计.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第0章作业: 教材P12-练习与实践 1.写出用符号’*’输出描绘汉字”大”的流程图。
2017北一女中 資訊能力競賽 暑期培訓營
C语言概述 第一章.
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
第3章 變數、算術運算、 數學函數及輸入輸出.
C语言复习3----指针.
C语言程序设计 教案 崔武子制作
函式庫補充資料.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Chap 5 函数 5.1 计算圆柱体积 5.2 数字金字塔 5.3 复数运算.
程式的時間與空間 Time and Space in Programming
C程序设计.
C语言程序设计 李祥 QQ:
C程序设计.
C++程式設計入門 變數與運算子 作者:黃建庭.
第2章 数据类型、运算符与表达式 本章要点: 基本数据类型 常量和变量 算术运算符和算术表达式 关系运算符和关系表达式
第2章 基本数据及其运算 本章学习的目标: 1、掌握基本数据的各种表示,基本数据常数的书写方法;
第四章 C 语言中的输入和输出.
第3章 最简单的C程序设计 3.1 顺序程序设计举例 3.2 数据的表现形式及其运算 3.3 C语句 3.4 数据的输入输出.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
Chap 7 数 组 7.1 排序问题 7.2 找出矩阵中最大值所在的位置 7.3 进制转换.
第二章 数据类型、运算符和表达式 §2.1 数据与数据类型 §2.2 常量、变量和标准函数 §2.3 基本运算符及其表达式 目 录 上一章
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
Chap 10 函数与程序结构 10.1 圆形体积计算器 10.2 汉诺塔问题 10.3 长度单位转换 10.4 大程序构成.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
函式庫補充資料 1.
Presentation transcript:

2017北一女中 資訊能力競賽 暑期培訓營 Anny@T.F.G

練習進度調查 https://goo.gl/forms/fDQRTAnYgOKTXDUo2

【培訓用書】 程式設計與演算法競賽入門經典(劉汝佳/著,H&C/譯) Part I 語言篇 chapter 01 程式設計入門 chapter 02 迴圈結構程式設計 chapter 03 陣列和字串 chapter 04 函數和遞迴 chapter 05 C++ 與 STL 入門 Part II 基礎篇 chapter 06 資料結構基礎 chapter 07 暴力求解法 Part III 競賽篇 chapter 08 高效演算法設計 chapter 09 動態規劃初步 chapter 10 數學概念與方法 chapter 11 圖論模型與演算法 chapter 12 進階專題 Appendix A 開發環境與方法 主要參考書目 【培訓用書】 程式設計與演算法競賽入門經典(劉汝佳/著,H&C/譯) http://www.books.com.tw/products/0010650143

【APCS】 大學程式設計先修檢測 程式設計觀念題 程式設計實作題 單選題,以運算思維、問題解決與程式設計觀念測試為主。 測試包含 code tracing, code completion, code debugging 等題型。 題目若需提供程式片段,則以 C subset 語言命題(參考文件下載  )。 作答結果由系統自動儲存,無須上傳。 >>>查看觀念題_範例試題   程式設計實作題 實作題,撰寫完整程式或副程式。 測驗者可自選程式語言( C, C++, Java, Python )撰寫程式。 須透過系統上傳原始程式碼。若上傳多次,評分時以最後上傳版本為準。 >>>查看實作題_範例試題 https://apcs.csie.ntnu.edu.tw/index.php/samplequestions

【APCS】 命題範圍 (2016.12.22更新) Programming Concepts Data types, constant, variable, Global, Local Control structures Loop structures Functions Recursion Array and Structures

【APCS】 大學程式設計先修檢測 《觀念題》 https://apcs.csie.ntnu.edu.tw/index.php/samplequestions/conceptquestions 《實作題》 https://apcs.csie.ntnu.edu.tw/index.php/samplequestions/implementationquestions

【培訓課程】 Day1: 程式競賽基礎 Day2: 陣列與字串 Day3: 函數與遞迴 Day4: 搜尋、排序、堆疊、佇列

Day1: 程式競賽基礎 C語言輸入輸出 掌握整數與浮點數含義(數值範圍)與輸出方法 理解程式競賽三步曲:輸入、計算、輸出 掌握迴圈(for, while), 計數器、累加器使用 學會程式逐步除錯方法(變數watch功能) 學會用fopen的方式讀寫檔案

C語言輸入輸出格式 #include <stdio.h> int main() { int a, b; scanf("%d%d", &a, &b); printf("%d\n", a+b); return 0; } Hint: stdio.h scanf printf &a &b int %d \n return 0

例題1-1 圓柱體的表面積 輸入底面半徑r和高h, 輸出圓柱體的表面積。 保留3位小數,格式請見範例。 範例輸入: 3.5 9 範例輸出: Area = 274.889

解析:表面積=上底面積+下底面積+側面積 Hint: math.h const Pi = acos(-1.0); double %lf float %f int %d return 0 #include <stdio.h> #include <math.h> int main() { const double pi = acos(-1.0); double r, h, s1, s2, s; scanf("%lf%lf", &r, &h); s1 = pi * r * r; s2 = 2 * pi * r * h; s = s1 * 2.0 + s2; printf("Area = %.3lf\n", s); return 0; }

例題1-2 三位數反轉 輸入一個三位數,分離出它的百位、十位和個位,反轉後輸出。 範例輸入 127 範例輸出 721

例題1-2 三位數反轉(1) #include <stdio.h> int main() { int n; scanf("%d", &n); printf("%d%d%d\n", n%10, n/10%10, n/100); return 0; }

例題1-2 三位數反轉 測資: 520 輸出結果: 025 還是 25

例題1-2 三位數反轉(2) #include <stdio.h> int main() { int n, m; scanf("%d", &n); m = (n%10)*100 + (n/10%10)*10 + (n/100); printf("%03d\n", m); return 0; }

例題1-2 三位數反轉 測資: 520 123 200 輸出結果: 025 321 002

例題1-3 交換變數 輸入兩個整數a和b, 交換二者的值,然後輸出。 範例輸入 824 16 範例輸出 16 824

例題1-3 交換變數 (三變數法) #include <stdio.h> int main() { int a, b, t; scanf("%d%d", &a, &b); t = a; a = b; b = t; printf("%d %d\n", a, b); return 0; }

例題1-4 雞兔同籠 已知雞和兔的總數量為n, 總腳數為m。輸入n和m,依次輸出雞的數目和兔的數目。如果無解,則輸出「No answer」(不要引號)。 範例輸入1 14 32 範例輸出1 12 2 範例輸入2 10 16 範例輸出2 No answer

例題1-4 雞兔同籠 分析:(已知雞和兔的總數量為n, 總腳數為m) 設雞有 a 隻,兔有 b隻,則 a+b = n 2a+4b=m 解聯立,得 a = (4n-m)/2 b= n-a; 思考:何時為無解呢? 正確的是:a, b 皆為整數且 a,b皆必須為非負數。

例題1-4 雞兔同籠 Hint: a, b 皆為整數且 a,b皆必須為非負數 Why m%2==1 #include <stdio.h> int main() { int a, b, n, m; scanf("%d%d",&n,&m); a = (4*n-m) / 2; b = n - a; if (m % 2 == 1 || a <0 || b<0) printf("No answer\n"); else printf("%d %d\n", a, b); return 0; }

例題1-5 三整數排序 輸入3個整數,從小到大排序後輸出 範例輸入: 20 7 33 範例輸出: 7 20 33 Hint: a, b,c a c b b a c b c a c a b c b a

例題1-5 三整數abc排序 #include <stdio.h> int main() { int a, b, c; scanf("%d%d%d", &a, &b, &c); if (a<=b && b<=c) printf("%d %d %d\n", a, b, c); else if (a<=c && c<=b) printf("%d %d %d\n", a, c, b); else if (b<=a && a<=c) printf("%d %d %d\n", b, a, c); else if (b<=c && c<=a) printf("%d %d %d\n", b, c, a); else if (c<=a && a<=b) printf("%d %d %d\n", c, a, b); else if (c<=b && b<=a) printf("%d %d %d\n", c, b, a); return 0; }

例題1-5 三整數abc排序 #include <stdio.h> int main() { int a, b, c, t; scanf("%d%d%d", &a, &b, &c); if (a>b) { t = a; a = b; b = t;} //執行完畢後 a<=b if (a>c) { t = a; a = c; c = t;} //執行完畢後 a<=c 且 a<=b if (b>c) { t = b; b = c; c = t;} printf("%d %d %d\n", a, b, c); return 0; }

總結 比賽時 無論使用C語言程式還是C++程式,都要把程式存成 .cpp,並且與C++ 程式提交。 留意格式問題 重視實驗 學會模仿 int %d float %f double %lf long long %lld (%I64d MinGw gcc) %.3lf, %.0lf, %.2f %3d %03d printf("…..\n") return 0; 重視實驗 學會模仿

簡單習題 3 數平均數(average.cpp) 攝氏(c)華氏(f)溫度轉換(temperature.cpp) 連續數字a…b之和(sum.cpp) n(n<360)度的正弦與餘弦(sincos.cpp) 打折(discount.cpp) 三角形判定(triangle.cpp) 閏年判定(year.cpp)

迴圈結構程式設計 For, while… 迴圈的使用方法 計數器、累加器 輸出中間結果除錯 使用計時函數測式效率 學會 freopen()重新導向方式讀寫檔案 學會 fopen()的方式讀寫檔案

for 迴圈 #include <stdio.h> int main() { int a=1,b=10; int sum=0; for (int i = a; i<= b; i++) sum += i; printf("%d\n", sum); return 0; } Hint: 觀察 i ,sum 的變化

Code Block Debugger(1) 開新專案(File/new/project…/console application/Go, Next, C++, project title, 例:myproject)

Code Block Debugger(2) 寫程式(在main.cpp裡寫程式)

Code Block Debugger(3) 按右鍵增加紅色中斷點Add breakpoints

Code Block Debugger(4) 開始除錯 (F8) 停止除錯 (Shift –F8)

Code Block Debugger(5) 觀看變數 Add watches Run to cursor / next line

例題2-1 aabb 完全平方數 輸出所有像是aabb的四位完全平方數 即, 前兩位數字相等,後兩位數字也相等 思考:1100,1111,1122,1133,1144,…,9999 那些是完全平方數

例題2-1 aabb 完全平方數 分析:n = aabb n = a * 1100 + b * 11 (a:1~9, b:0~9) m = sqrt(n) 四捨五入後的整數 再判斷 m2 是否等於 n

例題2-1 aabb 完全平方數 #include <stdio.h> #include <math.h> int main() { for (int a = 1; a<=9; a++) for (int b=0; b<=9; b++) int n = a * 1100 + b*11; int m = floor(sqrt(n)+0.5) ; if (m*m == n) printf("%d\n",n); } return 0; Hint: n = a * 1100 + b * 11 (a:1~9, b:0~9) m = sqrt(n) 四捨五入後的整數 再判斷 m2 是否等於 n Hint: sqrt()函數 floor()函數

例題2-2 3n+1問題 對於任意大於1的自然數n,若n為奇數,則將n變為3n+1, 否則變為n的一半。 經過若干次這樣的變換,一定會使n變為1。 例如:3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1。 輸入n, 輸出變換的次數。 N <= 109。 範例輸入 3 範例輸出 7

例題2-2 3n+1問題 解題分析: 迴圈的次數不確定, n也不是遞增、遞減式的迴圈 適合使用 while迴圈 if (n 是奇數) n = 3*n + 1 else n=n/2 一直做,直到 n 為 1

例題2-2 3n+1問題 #include <stdio.h> int main() { int n, count = 0; scanf("%d", &n); while(n > 1) if (n%2==1) n = 3*n + 1; else n = n/2; count ++; } printf("%d\n", count); return 0; Hint: 初始化問題 迴圈重複條件 == 運算子 注意輸出結果要換行 \n

例題2-2 3n+1問題 測試一下: 3 11111 555555 987654321 -- 7 55 146 1 Hint: 不要忘記測試 一個看起來正確的程式可能隱含錯誤 若觀察無法找出錯誤,可以「輸出中間結果」

例題2-2 3n+1問題 Hint: 不要忘記測試 一個看起來正確的程式可能隱含錯誤 若觀察無法找出錯誤,可以「輸出中間結果」 留意 溢位 問題 思考: int 32 位元整數 %d 數值範圍 -231 ~ 231-1 -2147483648 ~ 2147483647 long long 64位元整數 %lld (或 %I64d) -263 ~ 263-1

例題2-2 3n+1問題 Hint: long long n; 解決溢位問題 n <= 109 n = 3*n + 1 #include <stdio.h> int main() { int n2, count = 0; scanf("%d", &n2); long long n = n2; while(n > 1) if (n%2==1) n = 3*n + 1; else n = n/2; count ++; } printf("%d\n", count); return 0; Hint: long long n; 解決溢位問題 n <= 109 n = 3*n + 1

例題2-2 3n+1問題 測試一下: 3 11111 555555 987654321 -- 7 55 146 1  180 Hint: 不要忘記測試 一個看起來正確的程式可能隱含錯誤 若觀察無法找出錯誤,可以「輸出中間結果」

例題2-3 近似計算 計算 pi/4 = 1 – 1/3 + 1/5 – 1/7 +… 直到最後一項小於10-6

例題2-3 近似計算 計算 pi/4 = 1 – 1/3 + 1/5 – 1/7 +… 直到最後一項小於10-6 分析: i =0 ~ (未知), i++ 第i項( term )= 1.0 / (i*2+1) 處理一正一負的問題 一直做,直到 term <10-6

#include <stdio.h> int main() { double sum = 0; for (int i=0; ; i++) double term = 1.0 / (i*2 +1); if (i%2==0) sum += term; else sum -= term; if (term < 1e-6) break; } printf("%.6lf\n",sum); return 0; 例題2-3 近似計算 Hint: for (int i=0; ; i++) { if (….) break; } 1e-6: 1* 10-6

程式競賽中的輸入輸出框架 Hint:重複輸入 輸入完畢先按Enter, 再按Ctrl-Z, 最後再按Enter, 即可結束輸入 while (scanf("%d", &n) == 1) { // } while (scanf("%d%d", &n, &m) == 2) Hint:重複輸入 輸入完畢先按Enter, 再按Ctrl-Z, 最後再按Enter, 即可結束輸入

例題2-5 資料統計 輸入一些整數,求它們的最小值、最大值和平均值(保留3位小數)。 輸入保證這些數都不超過1000。 範例輸入:2 8 3 5 1 7 3 6 範例輸出:1 8 4.375

例題2-5 資料統計 (bug) Hint: 初值設定的重要性 #include <stdio.h> int main() { int x, n=0, min, max, s= 0; while (scanf("%d", &x)==1) s += x; if (x < min) min = x; if (x > max) max = x; n++; } printf("%d %d %.3f", ,min, max, (double)s /n); return 0; Hint: 初值設定的重要性

例題2-5 資料統計 (重新導向) Hint: freopen() #ifdef #define #define LOCAL #include <stdio.h> #define INF 1000000000 int main() { #ifdef LOCAL freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif // LOCAL int x, n=0, minx = INF, maxx= -INF, s= 0; while (scanf("%d", &x)==1) s += x; if (x < minx) minx = x; if (x > maxx) maxx = x; //printf("%d %d %.3f", ,minx, maxx, (double)s /n); n++; } printf("%d %d %.3f",minx, maxx, (double)s /n); return 0; 例題2-5 資料統計 (重新導向) Hint: freopen() #ifdef #define

#include <stdio. h> #define INF 1000000000 int main() { FILE #include <stdio.h> #define INF 1000000000 int main() { FILE *fin, *fout; fin = fopen("data.in", "rb"); fout = fopen("data.out", "wb"); int x, n=0, minx = INF, maxx= -INF, s= 0; while (fscanf(fin, "%d", &x)==1) s += x; if (x < minx) minx = x; if (x > maxx) maxx = x; //printf("%d %d %.3f", ,minx, maxx, (double)s /n); n++; } fprintf(fout, "%d %d %.3f",minx, maxx, (double)s /n); fclose(fin); fclose(fout); return 0; 例題2-5 資料統計 (fopen) Hint: FILE *fin, *fout; fin = fopen("data.in", "rb"); fout = fopen("data.out", "wb"); fclose(fin); fclose(fout); fscanf() fprintf()

習題 p2-22~p2-24 水仙花數(daffodil) 韓信點兵(hanxin) 倒三角形(triangle) 子序列之和(subsequence) 分數化小數(decimal) 排列(permutation)

水仙花數(daffodil) 輸出100~999中的所有水仙花數。 水仙花數為3位數ABC並滿足 ABC = A3 + B3 + C3, 例如153 = 13 + 53 +33,則153為水仙花數。

韓信點兵(hanxin) 相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只看一下隊伍的排尾就知道總人數了。 輸入3個非負整數a,b,c,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。 已知總人數不小於10,不超過100。 範例輸入:2 1 6 範例輸出:41 範例輸入:2 1 3 範例輸出:No answer

倒三角形(triangle) 輸入正整數n<=20,輸出一個n層的倒三角形。例如,n=5時輸出如下: ######### ####### ##### ### #

#include <stdio.h> int main() { int n; scanf("%d", &n); for (int i = n; i >= 1; i--) for(int j = n; j > i; j--) //每一層前輸出的空格數,第一層沒有空格 printf(" "); for(int k = 2*i-1; k>0; k--) printf("#"); printf("\n"); } return 0; 倒三角形(triangle)

子序列之和(subsequence) 輸入兩個正整數<m<106,輸出1/n2 + 1/(n+1)2 + …… + 1/m2,保留5位小數。輸入包含多組資料,結束標記為n=m=0。提示:本題有陷阱。 範例輸入: 2 4 65536 655360 0 0 樣例輸出: Case 1:0.42361 Case 2:0.00001

#include <stdio.h> int main() { int n, m, i; while( scanf("%d%d", &n, &m) != EOF) double sum = 0; for(i = n; i <= m; i++) sum += 1.0/i/i; printf("%.5f\n", sum); } return 0; 子序列之和(subsequence)

子序列之和(subsequence) 本題陷阱在於n比較大時,n*n會溢出 所以 1/n^2 應該用 1/n/n 而不是 1/(n*n) 如果沒有sum = 0;,後面的輸出是前一次輸出和本次輸出之和。

分數化小數(decimal) 輸入正整數a, b, c,輸出a/b的小數形式,精確到小數點後c位。a, b <= 10^6,c <= 100。輸入包含多組資料,結束標記為a=b=c=0. 範例輸入: 1 6 4 0 0 0 範例輸出: Case 1:0.1667

//version 1 未考慮double型資料的有效數字只有15-16位 #include <stdio //version 1 未考慮double型資料的有效數字只有15-16位 #include <stdio.h> int main() { int a,b,c,count=1; while(scanf("%d%d%d",&a,&b,&c)!=EOF){ if(a==0&&b==0&&c==0) break; printf("Case %d:%.*lf\n",count++,c,(double)(a)/b); //printf("%*.*lf", x, y, z); //意思是輸出頻寬為x,小數點後y為的double型數據z } return 0; 分數化小數(decimal) 可用 1 6 58 測試。

分數化小數(decimal) 可用【3930 1687 4】、【3930 1687 3】測試。 //version 2 未考慮小數部分第c位是9,即四捨五入後還需進位 #include <stdio.h> int main() { int a,b,c,tmp,count=1; while (scanf("%d%d%d", &a, &b, &c) != EOF){ if (a==0 && b==0 && c==0) break; printf("Case %d:%d.", count++, a / b); //整數部分 a = a % b * 10 ; while(c-->1){ //小數點後前c-1位 printf("%d", a/b); a = a % b * 10; } tmp = a % b * 10 /b; //tmp是初始a/b的小數點後第c+1位元數字 if (tmp < 5) printf("%d\n", a / b ); else printf("%d\n", a / b + 1); return 0; 分數化小數(decimal) 可用【3930 1687 4】、【3930 1687 3】測試。

//version 3 #include <stdio //version 3 #include <stdio.h> int main() { int a,b,c,tmp,i,t,count=1; int s[110];//用於保存小數點後的部分 while(scanf("%d%d%d",&a,&b,&c)!=EOF){ if(a==0&&b==0&&c==0) break; t=a/b; a=a%b*10; for(i=1;i<c;i++){//小數點後前c-1位元保存到陣列s中 s[i]=a/b; } tmp=a%b*10/b;//tmp是初始a/b的小數點後第c+1位元數字 if(tmp<5) s[i]=a/b;//s[i]即s[c] else s[i]=a/b+1; while(i>1){ if(s[i]==10){ s[i]-=10; s[i-1]+=1; i--; if(s[1]==10){ s[1]-=10; t++; printf("Case %d:%d.",count++,t); for(i=1;i<=c;i++) printf("%d",s[i]); printf("\n"); return 0; 分數化小數(decimal)

排列(permutation)

Day2: 陣列與字串 掌握一維陣列、二維陣列的宣告與使用 memset, memcpy (string.h) 掌握字串宣告、指定值、比較與連接方式 熟悉ASCII碼與ctype.h的字元函數 競賽題目精選:UVa272, 10082, 401, 340, 1583, 1584 1585, 1586, 1225, 455, 227, 232, 1368, 202, 10340, 1587

3-1 逆序輸出 讀入不超過100個整數。 任務:逆序輸出,以空白隔開。 範例輸入:1 2 3 4 5 7 8 9 範例輸出:9 8 7 5 4 3 2 1 最後記得換行

3-1 逆序輸出 解析: 開一整數陣列 (思考大小 : 100? 10000?) 連續輸入放入陣列中 輸出格式

3-1 逆序輸出 #include <stdio.h> #define maxn 105 int a[maxn]; int main() { int x, n=0; while (scanf("%d", &x)==1) a[n++]=x; //連續讀入 for (int i = n-1; i>0; i--) printf("%d ", a[i]); //印出前n-1個 printf("%d\n", a[0]); //處理最後一個 return 0; } x 1 7 39 52 15 26 37 CtrlZ 2 3 4 5 6 a[0] a[1] a[2] a[3] a[4] a[5] a[6] n Hint: n++, maxn, 陣列宣告的位置 a[n++]=x; 代表 a[n]=x; N++; 輸出 a[6]~a[1]空格隔開 輸出 a[0] 換行

3-2 開燈問題 有 n 盞燈,編號為1~n。 第1個人把所有燈打開,第2個人下所有編號為2的倍數的開關(這些燈將被關掉) 第3個人按下所有編號為3的倍數的開關(關掉的燈將被打開,開著的燈將被關掉) 依此類推。 一共有 k 個人,問最後有哪些燈開著? 輸入:n和k,輸出:開著的燈的編號( k<= n <= 1000)。 範例輸入: 7 3 範例輸出: 1 5 6 7 1 2 3 4 5 6 7 1 2 3

3-2 開燈問題 if(j%i==0) a[j] = !a[j]; 解析:用 a[1], a[2], a[3], …, a[n] 表示編號為1,2,3,…,n的燈是否開著。 #include <stdio.h> #include <string.h> #define maxn 1010 int a[maxn]; int main() { int n, k; memset(a, 0, sizeof(a)); scanf("%d%d", &n, &k); for (int i=1; i<=k; i++) for (int j=1; j<=n; j++) if(j%i==0) a[j] = !a[j]; for (int i=1; i<=n; i++) if (a[i]) printf("%d", i); printf("\n"); return 0; } 1 2 3 4 5 6 7 1 2 3 3-2 開燈問題

#include <stdio. h> #include <string #include <stdio.h> #include <string.h> #define maxn 1010 int a[maxn]; int main() { int n, k, first = 1; memset(a, 0, sizeof(a)); scanf("%d%d", &n, &k); for (int i=1; i<=k; i++) for (int j=1; j<=n; j++) if(j%i==0) a[j] = !a[j]; for (int i=1; i<=n; i++) if (a[i]) { if (first) first = 0; else printf(" "); //避免多餘空格 設置一個旗標變數 first printf("%d", i); } printf("\n"); return 0; } 1 2 3 4 5 6 7 1 2 3 3-2 開燈問題

陣列與字串競賽題 char c; c = getchar(); putchar(c); char s[20]; scanf("%s", s); printf("%s", s);

例題3-1 TeX中的引號(Tex Quotes, Uva 272) TeX 是一種由 Donald Knuth 所發展出的一套文書排版軟體。這套軟體可以將原始文件檔加上一些像字型等型態後,轉成一份很漂亮的文件。而一份漂亮的文件是需要用 `` 和 " 來把別人說的話給「引」出來,而不是用大部份鍵盤上有的 " 。 如果原始文件檔內容是: "To be or not to be," quoth the bard, "that is the question." 我們需要把原始文件變成這個樣子: ``To be or not to be,'' quoth the bard, ``that is the question.''

TeX中的引號(Tex Quotes, Uva 272) "To be or not to be," quoth the bard, "that is the question." ``To be or not to be,'' quoth the bard, ``that is the question.'‘ 關鍵: 如何判斷是左引號還是右引號 如何輸入字串

TeX中的引號(Tex Quotes, Uva 272) // UVa272 Tex Quotes // Rujia Liu #include<stdio.h> int main() { int c, q = 1; while((c = getchar()) != EOF) { if(c == '"') { printf("%s", q ? "``" : "''"); q = !q; } else printf("%c", c); } return 0;

TeX中的引號(Tex Quotes, Uva 272) if(c == '"') { printf("%s", q ? "``" : "''"); q = !q; } else printf("%c", c); if(c == '"'){ printf("%s", q ? "``" : "''"); q = !q; } else printf("%c", c); Hint: q 為旗標變數 q = 1 !q = 0 q = !q (正反正反…)

例題3-2 WERTYU (UVa10082) 打字時一個常見的錯誤就是沒有把手放在正確位置,而是偏右邊一個位置。所以會發生Q被打成W,J被打成K等等的情況。你的任務就是要把打錯的字修正回來。 範例輸入 O S, GOMR YPFSU/ URD. ,U [JPMR MI,NRT OD 8346333 範例輸出 I AM FINE TODAY. YES, MY PHONE NUMBER IS 7235222

WERTYU (UVa10082) #include<stdio.h> // UVa10082 WERTYU // Rujia Liu #include<stdio.h> char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"; int main() { int i, c; while((c = getchar()) != EOF) { for (i=1; s[i] && s[i]!=c; i++); // 找錯位之後的字元在常量表中的位置 if (s[i]) putchar(s[i-1]); // 如果找到,則輸出它的前一個字元 else putchar(c); } return 0; WERTYU (UVa10082)

例題3-3 迴文(Palindromes, UVa401) 迴文的定義為正向,反向讀到的字串均相同. 如:abba , abcba ... 等就是迴文 請判斷一個字串(長度 < 1000)是否是一個迴文? 範例輸入 : abba Abcd 範例輸出 : yes no

#include<stdio. h> #include<string #include<stdio.h> #include<string.h> int main() { char s[30]; while(scanf("%s", s) == 1) int len = strlen(s); int p = 1; for(int i = 0; i < (len+1)/2; i++) if (s[i] != s[len-1-i]) p = 0; // 不是回文串 if (p) printf("yes\n"); else printf("no\n"); } return 0; 迴文

例題3-4 猜數字遊戲提示(Master-Mind Hints, Uva 340) 實現一個經典"猜數字"游戲。 給定答案序列和用戶猜的序列,統計有多少數字位置正確(A),有多少數字在兩個序列都出現過但位置不對(B)。 輸入包含多組數據。 每組輸入第一行爲序列長度n, 第二行是答案序列,接下來是若干猜測序列。 猜測序列全0時該組數據結束。 n=0時輸入結束。

例題3-4 猜數字遊戲提示(Master-Mind Hints, Uva 340) 範例輸入: 4 1 3 5 5 1 1 2 3 4 3 3 5 6 5 5 1 6 1 3 5 0 0 0 0 10 1 2 2 2 4 5 6 6 6 9 1 2 3 4 5 6 7 8 9 1 1 1 2 2 3 3 4 4 5 5 1 2 1 3 1 5 1 6 1 9 1 2 2 5 5 5 6 6 6 7 0 0 0 0 0 0 0 0 0 0 範例輸出: Game 1: (1,1) (2,0) (1,2) (4,0) Game 2: (2,4) (3,2) (5,0) (7,0)

// UVa340 Master-Mind Hints // Rujia Liu #include<stdio // UVa340 Master-Mind Hints // Rujia Liu #include<stdio.h> #define maxn 1000 + 10 int main() { int n, a[maxn], b[maxn]; int kase = 0; while(scanf("%d", &n) == 1 && n) { // n=0時輸入結束 printf("Game %d:\n", ++kase); for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(;;) { int A = 0, B = 0; for(int i = 0; i < n; i++) { scanf("%d", &b[i]); if(a[i] == b[i]) A++; } if(b[0] == 0) break; // 正常的猜測序列不會有0,所以只判斷第一個數是否爲0即可 for(int d = 1; d <= 9; d++) { int c1 = 0, c2 = 0; // 統計數字d在答案序列和猜測序列中各出現多少次 if(a[i] == d) c1++; if(b[i] == d) c2++; if(c1 < c2) B += c1; else B += c2; printf(" (%d,%d)\n", A, B-A); return 0; 猜數字遊戲提示

https://github.com/aoapc-book/aoapc-bac2nd/tree/master/ch3

Day3: 函數與遞迴 學會定義區域變數與全域變數 自定函數與結構 函數呼叫與參數傳遞 理解遞迴定義與遞迴函數 熟悉Stack segment,了解stack overflow的常見原因 例題:Uva1339, 489, 133, 213, 512, 12412

Day4:搜尋、排序、堆疊、佇列 熟悉C++版競賽程式框架 熟練並掌握string 與 stringstream 熟練STL中的排序與檢索等相關函數 熟練STL中的vector容器 理解堆疊、佇列與優先佇列的概念 掌握亂數產生方法,自行設計測資 UVa 10474, 101, 136, 221

Day5:資料結構基礎 Stack, queue, 運算式解析 二元樹與走訪 圖的DFS與BFS 拓撲排序演算法、尤拉迴路 Uva 514, 10305