程式的時間與空間 Time and Space in Programming

Slides:



Advertisements
Similar presentations
index 目次 ( 請按一下滑鼠,解答就會出現喔 !) 接續下頁解答 3-1 極限的概念.
Advertisements

While 迴圈 - 不知重複執行次數
CSIM, PU C Language Introduction to the C Programming Language 重覆敘述 (for,while,break,continue) 適合重複性的計算或判斷.
會計資訊系統 專章A.
第三章 調整與編表.
迴圈 迴圈基本觀念 while迴圈 do 迴圈 for迴圈 巢狀迴圈 迴圈設計注意事項 其他控制指令 迴圈與選擇的組合.
中五級中史科及通識科跨科研習 研習大澳的「宗教文化」─ 廟宇的研習 指導老師:周婉儀老師 組員: 陳偉欽 5a (15)
计算机三级考试C语言上机试题专题.
Loops.
C#程序设计案例教程 第3章 程 序 结 构.
您買美元了嗎? 退休規劃 全球外幣保單.
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
上課囉 職場甘苦談 小資男孩向錢衝 育碁數位科技 呂宗益/副理.
第 5 章 流程控制 (一): 條件分支.
欢迎再次走进 思想政治的课堂.
教師敘薪實務解說 大墩國小人事室 吳莉真
第二章 JAVA语言基础.
國語文好點子趴辣客教學食譜 甜點:〈焦糖鳥布蕾〉
第一章 程序设计入门.
Introduction to the C Programming Language
高级语言程序设计 主讲人:陈玉华.
CH2 開發環境介紹 最簡單的互動設計 – Arduino一試就上手 孫駿榮、吳明展、盧聰勇.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
Class 2 流程控制-選擇敘述與迴圈.
C++Primer 3rd edition 中文版 Chap 5
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
If … else 選擇結構 P27.
Chap 2 用C语言编写程序 2.1 在屏幕上显示 Hello World! 2.2 求华氏温度 100°F 对应的摄氏温度
C 程式設計— 控制敘述 台大資訊工程學系 資訊系統訓練班.
搜尋資料結構 Search Structures.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
程式撰寫流程.
流程控制、陣列 台南市聖功女子高級中學 毛全良.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
Introduction to the C Programming Language
作弊是否很有诱惑性? 上堂课已经讲了 作业不一定在两个小时里都能完成 答疑没有一个人? 作弊是有记录的 心理系很多同学集体作弊,让人震惊
實作輔導 3 日期: 4/14(星期六) 09:10~12:00、13:10~16:00
計數式重複敘述 for 迴圈 P
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
共有六個運算性質 包括它的證明以及相關題型
C语言概述 第一章.
程式結構&語法.
4 條件選擇 4.1 程式基本結構 循序式結構 選擇式結構 重複式結構 4-3
我喜歡英文中的中年代稱,不是 mid-age 這麼赤裸裸的直稱,而是用 prime time - 黃金時間
课题2 宏程序编程介绍 1、宏变量 2、常量 3、运算符与表达式 4、赋值语句 5、条件判别语句IF,ELSE,ENDIF
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
Introduction to the C Programming Language
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Chap 5 函数 5.1 计算圆柱体积 5.2 数字金字塔 5.3 复数运算.
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
本节内容 Lua基本语法.
Introduction to the C Programming Language
累堆排序法 (Heap Sort).
第11章 物件互動行為塑模.
第7章 概率算法 欢迎辞.
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
本节内容 指针类型.
if (j…) printf ("… prime\n"); else printf ("… not prime\n");
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
智慧財產權管理講次36 積體電路電路布局保護法(1) 主講:吳銘圳
PPT注意事项: 当前PPT课件文件必须和提供的源代码文件夹“代码”在同一目录中即不要移动文件夹“代码”的默认位置。
多重條件選擇敘述
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
判斷(選擇性敘述) if if else else if 條件運算子.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
1.2.3 循环语句.
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第四章 買賣業會計.
第二章 Java基本语法 讲师:复凡.
函式庫補充資料 1.
Presentation transcript:

程式的時間與空間 Time and Space in Programming 國立中山大學 資訊工程學系 平行處理實驗室 林必祥 李協彥 2017/11/18

TLE 在CPE評判系統中,若程式執行過久(約超過3秒),會直接判定不通過 Why ? 如果沒有時間的限制,每道題目都超超超超暴力解,就能找到正確解答  人人都能解 7 題 !!

降低運算時間 刪除不必要的判斷、運算  要有好的算法,而不是傻傻的算 如果有重複的計算,可以將運算結果存起來,之後就不必再重新算  用空間來換取時間 !!

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? + + + + + + + +

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-1: 假設用了 i 個10元、 j 個5元、 k 個1元,每種硬幣可能的個數如下 i ( 10 元 ) : 0, 1, 2, 3, 4, 5 j ( 5 元 ) : 0, 1, 2, 3, …… , 9, 10 k ( 1 元 ) : 0, 1, 2, 3, ………… , 49, 50 採用窮舉法,嘗試各種(i, j, k)的組合,並利用下面的判斷式: 10i + 5j + k = 50 ? 便能計算出所有硬幣的組合。

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-1: int i , j , k , ans = 0 , loop = 0; for( i = 0 ; i <= 5 ; i++) for( j = 0 ; j <= 10 ; j++) for( k = 0 ; k <= 50 ; k++) { loop++; if ( i * 10 + j * 5 + k == 50 ) ans++; } printf(“共 %d 種,迴圈執行了 %d 次\n”, ans , loop ); 共 36 種,迴圈執行了 3366 次

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-2: 如果k不是5的倍數,便不可能轉換,因此可以排除掉那些情況 i ( 10 元 ) : 0, 1, 2, 3, 4, 5 j ( 5 元 ) : 0, 1, 2, 3, …… , 9, 10 k ( 1 元 ) : 0, 5, 10, 15, 20, ………… , 45, 50 ------------------------------------------------------------------- for( i = 0 ; i <= 5 ; i++) for( j = 0 ; j <= 10 ; j++) for( k = 0 ; k <= 50 ; k+=5) 共 36 種,迴圈執行了 726 次

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-3: 當 i * 10 + j * 5 + k == 50 時,應立即跳出k的迴圈,因為再增加k值 也不會是解了。 if ( i * 10 + j * 5 + k == 50 ) { ans++; break; } 共 36 種,迴圈執行了 491 次

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-4: 當 i 和 j 的值固定之後,k的值只有一種選擇,因此不必考慮 k 的變化情形 當 i = 0, j 可能為0, 1, 2, 3, ......, 10  ( 50 – i * 10 ) / 5 = 10 當 i = 1, j 可能為0, 1, 2, 3, ...., 8  ( 50 – i * 10 ) / 5 = 8 當 i = 2, j 可能為0, 1, 2, 3, ..., 6  ( 50 – i * 10 ) / 5 = 6 ... 當 i = 5, j 可能為0  ( 50 – i * 10 ) / 5 = 0

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-4: for( i = 0 ; i <= 5 ; i++) for( j = 0 ; j <= (50-i*10)/5 ; j++) { loop++; ans++; } printf(“共 %d 種,迴圈執行了 %d 次\n”, ans , loop ); 共 36 種,迴圈執行了 36 次

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-5: 由上個方法得知,當 i 的質固定後,j 的變化情形只有 (50-i*10)/5種, 0 ~ (50-i*10)/5 中,每個值都是一種換硬幣的組合。 因此只需要對 i 作迴圈,就能加總出答案。 for ( i = 0 ; i <= 5; i++ ) { loop++; number += (50 – i * 10 ) / 5 + 1 ; } 共 36 種,迴圈執行了 6 次

問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法-6: 我們所計算的值,其實是一個等差級數,即 11 + 9 + 7 + 5 + 3 + 1 = 6 * ( 11+1) / 2 = 36 ------------------------------------------------------ int number = 0, a, b, n = 50 ; a = n / 5 + 1 ; if( a % 2 == 0 ) b = 2 ; else b = 1 ; number = ( a + b ) * ( ( a – b ) / 2 + 1 ) / 2 ; printf(“共 %d 種\n”, number ) ; 共 36 種

程式執行時間的差異 問題:將50元硬幣換成等值的1元、5元、10元硬幣的方法共有多少種? 方法 運算執行次數 1 3366 2 726 3 491 4 36 5 6

用空間來換取時間 問題:若給你一個整數𝑝 ( 1<𝑝<1000000 ),請判斷這個數是否為質數? 方法:從2到 𝑝 ,每個數字都檢查能不能整除 𝑝,如果都不行, 那 𝑝 就是質數。 int i , p , prime=1; for ( i = 2; i <= sqrt(p) ; i++ ) if( p % i == 0 ) prime=0; 𝑝 是質數 1 prime 𝑝 不是質數 迴圈執行: 𝑝 −1 次

問題:在陣列p中存有 10 個整數( 1<𝑝[𝑖]<1000000 ),請判斷這個陣 列中,哪些數字為質數? 方法:對於每個數字𝑝[𝑖],一樣從2 ~ 𝑝 ,每個數字都檢查能不能整 除 𝑝[i],如果都不行,那 𝑝[𝑖] 就是質數。 int p[10], i , j , prime; for ( i = 0 ; i <10 ; i++ ) { prime=1; for ( j = 2; j <= sqrt( p[i] ) ; j++ ) if( p % j == 0 ) prime=0; } 𝑝[𝑖] 是質數 1 prime 𝑝[𝑖] 不是質數 迴圈執行:10∗( 𝑝 −1) 次

假設今天會給你100,000個數,每個數的值差不多10,000 用剛剛的方法,迴圈執行的次數約為 100000 * 100 = 10000000次。 這麼多次的運算,等程式執行完天都黑了。 如果可以建出一個清單,列出數字範圍內中哪些數是質數, 那麼每次讀取一個數只需要核對這個清單,就能知道是不是質數了!

質數表 對於一個數字 N , 我們可以建出一張表來標示 1~N 中每個數字分別為 質數或合數。 建立的方法: 篩法。

質數表建立:篩法 窮舉所有的合數,並標記這些合數, 最後沒被標記到的便是質數! example : 1.刪掉2的倍數 : 4, 6, 8, 10, ...... 直到超過N 2.找到下一個還沒被刪的數,是3 刪掉3的倍數:6,9,12,..... 直到超過N 3.找到下一個還沒被刪的數,是5  刪掉5的倍數:10,15,20,...直到超過N .... n.直到N之前都檢查過為止

範例 假設我們要建一個 N = 20 的質數表 (bool prime[21];) index value 1 false 2 true 3 4 5 6 7 8 9 10 index value 11 true 12 13 14 15 16 17 18 19 20

範例 從2開始,標記2的倍數直到20為止。 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 13 14 15 16 17 18 19 20

範例 從2開始,標記2的倍數直到20為止。 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 false 13 14 15 16 17 18 19 20

範例 找到下個沒被找過的數字:3,於是標記3的倍數 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 false 13 14 15 16 17 18 19 20

範例 找到下個沒被找過的數字,是3,於是標記3的倍數 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 false 13 14 15 16 17 18 19 20

範例 找到下個沒被找過的數字,是5,於是標記5的倍數 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 false 13 14 15 16 17 18 19 20

範例 找到下個沒被找過的數字,是5,於是標記5的倍數 index value 1 false 2 true 3 4 5 6 7 8 9 10 11 true 12 false 13 14 15 16 17 18 19 20

範例 依此類推,直到找到20為止,就建出一個質數表了! index value 1 false 2 true 3 4 5 6 7 8 9 10 index value 11 true 12 false 13 14 15 16 17 18 19 20

範例 如果我要知道13是不是質數,只需 要看質數表中第13個值為何: true 代表這個數是質數。 false 代表這個數是合數。 上述的查表動作,只需要 1 個運算 就能達成,而不用重新檢查每個數 字是否能整除13。 index value 1 false 2 true 3 4 5 6 7 8 9 10 index value 11 true 12 false 13 14 15 16 17 18 19 20

質數表建立:程式碼 bool prime[1000] ; void build_table( ) { for( int i = 0; i < 1000; i++ ) prime[ i ] = true; prime[ 0 ] = prime[ 1 ] = false; for(int i = 2; i < 1000; i++ ) if( prime[ i ] ) for( int j= i * 2; j < 1000; j = j + i ) prime[ j ] = false; } 初始化 刪除質數 i 的倍數 j = i 的所有倍數

質數表有比較好嗎 質數表的價值: 雖然一開始在建表的時候會花些時間,但後來在判斷是否為質數時, 就能節省大量的時間。 當你的測資很過分,都是很多而且很大的數字,此時查質數表遠比每個數 字都慢慢算還快許多!

題目演練 題目:UVA 543 題目敘述:「任何大於4的偶數,都可以寫成兩個質數相加。」 需要你寫一個程式來驗證上述的定理是否成立! 輸入測資:不定數量的整數,每個整數範圍為6≤𝑛<1000000。 輸出答案:如果定理成立,便印出 n = a + b,其中a,b為質數,且b-a 是最大值。反之如果不成立,印出 Goldbach’s conjecture is wrong.

題目演練-UVA543

題目演練-UVA543 解法: 先建出大小為1,000,000質數表,再針對每個讀進來的整數n, 從3開始檢查是否有兩個質數a , b 可以達成n = a + b。 for ( i = 3 ; i < n ; i++ ) { if ( prime [ i ] && prime [ n – i ]) // true = 質數 找到答案囉  }

題目演練-UVA543 i index value 1 false 2 true 3 4 5 6 7 8 9 10 11 12 Example : n = 12 當 i = 3 確認 3 和 12 – 3 是否都是質數  12 – 3 = 9 不是質數 i

題目演練-UVA543 i index value 1 false 2 true 3 4 5 6 7 8 9 10 11 12 Example : n = 12 當 i = 4 確認 4 和 12 – 4 是否都是質數  4和12 – 4 = 8 都不是質數 i

題目演練-UVA543 i index value 1 false 2 true 3 4 5 6 7 8 9 10 11 12 Example : n = 12 當 i = 5 確認 5 和 12 – 5 是否都是質數  5和12 – 5 = 7 都是質數 !! 找到答案囉  print 12 = 5 + 7 i

UVA_543 部分程式碼 build_table( ); while( scanf(“%d”, &n ) && n ) { for( i = 3; i <= n / 2 ; i++ ) if( prime [ i ] && prime [ n – i ] ) printf(“%d = %d + %d\n”, n , i , n – i ); break; } if( i > n / 2 ) // i > n / 2 代表沒有找到解 printf(“Goldbach’s conjecture is wrong.\n”);

Q & A