210 likes | 337 Views
Light, more light. 99703022 林依柔 99703024 江翰臻 99703033 鄧思維. 簡介. Light, more light. 學校有一個工友他負責開關走廊中的電燈泡。每個燈泡有他自己的開關。也就是說你按下某個燈泡的開關,燈泡就亮了。下一次你再按這個開關,這個燈泡就熄了。 然而這個工友有個古怪的習慣,假如走廊有 n 個燈泡(編號從 1 到 n ),他會來回走上 n 趟。在第 i 趟開始走過去的時候,他會開關燈泡編號可以被 i 除盡的燈泡,在回來的時候不做任何事。. 目標.
E N D
Light, more light 99703022 林依柔 99703024 江翰臻 99703033 鄧思維
Light, more light • 學校有一個工友他負責開關走廊中的電燈泡。每個燈泡有他自己的開關。也就是說你按下某個燈泡的開關,燈泡就亮了。下一次你再按這個開關,這個燈泡就熄了。 • 然而這個工友有個古怪的習慣,假如走廊有n個燈泡(編號從1到n),他會來回走上n趟。在第 i趟開始走過去的時候,他會開關燈泡編號可以被 i除盡的燈泡,在回來的時候不做任何事。
目標 • 現在你的任務就是要算出在走完n趟之後,最後一個電燈泡(編號n)是亮著的還是暗著的。 • 假設剛開始時所有的電燈都是暗著的。
輸入 • 每個測試資料一行,包含一個整數n (n <= 232-1),代表走廊共有多少個燈泡。 • n=0代表輸入結束。
輸出 • 如果最後一個燈泡是亮著的請輸出yes,如果是暗著的請輸出no。
例子1 • 輸入 : 3 • 輸出 : NO • 第一趟 可被1除盡的數(1 、 2 、 3) • 第二趟 • 可被2除盡的數(2) • 第三趟 • 可被3除盡的數(3)
例子2 • 輸入 : 4 • 輸出 : YES • 第一趟 • 可被1除盡的數(1、2、3、4) • 第二趟 • 可被2除盡的數(2 、 4) • 第三趟 • 可被3除盡的數(3) • 第四趟 • 可被4除盡的數(4)
用Array實做暴力解法 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 有九個燈 0 0 0 0 0 0 0 0 0 工友經過走廊第一次,碰觸可被1整除的編號燈泡的開關 Array[ i ] 由0(關) → 1(開) 1 1 1 1 1 1 1 1 1
用Array實做暴力解法 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 0 1 0 1 0 1 0 1 工友經過走廊第二次,碰觸可被2整除的編號燈泡的開關 Array[2]、Array[4] 、 Array[6] 、 Array[8]由1(開) → 0(關) 1 1 1 1 1 1 1 1 1 接下來依此類推
pseudo code boolDeterLight ( int n ) { bool Array [ n+1 ] = { false } //將所有編號的燈初始化為關燈 for i = 1 to n for j = i to n if ( j % i == 0 ) Array [ j ] to toggle ; // true → false 或 false → true return Array [ n ] }
暴力解的時間複雜度 主要的迴圈 for i = 1 to n for j = i to n 所以總共跑了 n! 次 時間複雜度 O(n!)
親身經歷 1 2 3 4 5 6 7 8 9 第一輪 第二輪 第三輪 第四輪
第五輪 • 1 2 3 4 5 6 7 8 9 第六輪 第七輪 第八輪 第九輪
1 2 3 4 5 6 7 8 9 1 7 1 3 1 1 2 1 2 4 1 5 1 2 3 6 1 2 4 8 1 3 9 偶數 開...關 不亮奇數開.關.開 亮 因數數目為奇數時,燈才會亮!
判斷n的因數個數 時間複雜度 O(n) • boolDeterLight (int n){ intnum = 1; for ( inti = 2 ; i <= n ; i++ ){ if ( n % i== 0 ) num++ ; } return ( num%2 == 1 ); // return true when odd • }
再次觀察 1 2 3 4 5 6 7 8 9 • GUESS: 應該是完全平方數?
其實只有完全平方數 因數個數才會是奇數!
直接判斷是否為完全平方數 n <= 232-1 • #include<stdio.h> • #include<math.h> • int main(){ • long longint n; • while( scanf("%lld",&n)==1 && n!=0 ){ • if( floor(sqrt(n)) == sqrt(n) ) printf("yes\n"); • else printf("no\n"); • } • return 0; • }