用Java實現“帶鎖的門”算法
題目:帶鎖的門:
在走廊上有n個帶鎖的門,從1到n依次編號。最初所有的門都是關着的。我們從門前經過n次,每次都從1號門開始。在第i次經過時(i = 1,2,…, n)我們改變i的整數倍號鎖的狀態;如果門是關的,就打開它;如果門是打開的,就關上它。在最後一次經過後,哪些門是打開的,哪些門是關上的?有多少打開的門?
一、算法分析:
從1-n的所有門,要經過n次:
- 若k(k<=n)可分解爲i*j(i!=j),則第k個門一定會有偶數次開關門的變化,則最後門的狀態還是關閉。
如k = 18,可以分解成1x18,2x9,3x6,則第1次,2次,3次,6次,9次,18次經過第18號門,均會變化開關門的狀態,原來是關門,經過偶數次變化,最終狀態還是關門。 - 若k爲完全平方數,如1、4、9、16,則第k個門只會有奇數次變化。
如k=4,只有1、2、4次經過會變化狀態,故最後門是開的。
按照如上的分析,我們只需要判斷1-n個門中有多少個完全平方數,即可確定開門的個數。
二、詳細代碼:
package Exercise2;
import java.util.ArrayList;
import java.util.Scanner;
public class theDoorWithLock {
public static void main(String[] args) {
System.out.println("請輸入帶鎖的門的個數:");
int n = new Scanner(System.in).nextInt();
//sum統計開門的個數
int sum = 0;
//open存儲開着的門的編號
ArrayList<Integer> open = new ArrayList<>();
for (int i = 1; i * i <= n; i++) {
open.add(i * i);
sum++;
}
//close存儲關閉的門的編號
ArrayList<Integer> close = new ArrayList<>();
for (int i = 1; i <= n; i++) {
if (!open.contains(i))
close.add(i);
}
System.out.println("打開的門的編號爲:");
for (Integer integer : open) {
System.out.print(integer + " ");
}
System.out.println("\r\n");
System.out.println("關着的門的編號爲:");
for (Integer integer : close) {
System.out.print(integer + " ");
}
System.out.println("\r\n");
System.out.println("打開的門的個數爲:" + sum);
}
}
三、運行結果: