用Java實現“帶鎖的門”算法

用Java實現“帶鎖的門”算法


題目:帶鎖的門:

在走廊上有n個帶鎖的門,從1到n依次編號。最初所有的門都是關着的。我們從門前經過n次,每次都從1號門開始。在第i次經過時(i = 1,2,…, n)我們改變i的整數倍號鎖的狀態;如果門是關的,就打開它;如果門是打開的,就關上它。在最後一次經過後,哪些門是打開的,哪些門是關上的?有多少打開的門?

一、算法分析:

從1-n的所有門,要經過n次:

  1. 若k(k<=n)可分解爲i*j(i!=j),則第k個門一定會有偶數次開關門的變化,則最後門的狀態還是關閉。
    如k = 18,可以分解成1x18,2x9,3x6,則第1次,2次,3次,6次,9次,18次經過第18號門,均會變化開關門的狀態,原來是關門,經過偶數次變化,最終狀態還是關門。
  2. 若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);
    }
}

三、運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章