2020年9月6日 星期日

河內塔 C++範例代碼 非遞迴詳細解說

河內塔 C++範例代碼 非遞迴詳細解說

玩法與規則

河內塔的玩法與規則詳細可以簡單看一下這一篇,裡面也有三階如何破關的演示。
https://sites.google.com/a/g2.nctu.edu.tw/unimath/2017-11/Hanoi

非遞迴解解法

再來直接進入主題,這個解法是直接看規則得出來的可能跟其他正規的解法不太一樣。
首先把這三個柱子分成 0 1 2 編號,並且制定的一些規則。
這張圖先看一眼,下面會解說上面的含意。

移動相關的說明

先說明移動的規則,這也是整個代碼最核心的部分。
以下的說明如果提到 無法移動 就是違反這些規則了。
  1. 只能把小的疊在大的上面
    遊戲本身的規則。不一定要差1,可以把1疊到3上面。
  2. 不要重複上一步驟
    這很直覺的別做沒有意義的行為,犯傻進入無限迴圈。

發牌

指從 [0柱] 移動到 [1柱] 或 [2柱] 的意思。
具體移動到哪個一個依據下面的情況 ,依據階層有不同的順序。
階層指的時候一開始的時候玩幾個盤子。
先發哪一柱會影響最後完成的柱在哪裡。依照底下規則可以保證完成柱在[2柱]
  • 奇數階層:每一次發牌的時候優先發[2柱]
  • 偶數階層:每一次發牌的時候優先發[1柱]
如果無法移動才發到另一柱,比如說奇數階層的時候,發牌無法發到2柱,那就往1柱發。
然後這裡有一點要注意的規則
  • <收牌>後不可以再<發牌>
就是說你發的時候要檢查一下,上一步有沒有收過牌
不管是從 [1柱] 或 [2柱] 收回來的都算。

收牌

指從 [1柱] 或 [2柱] 移動到 [0柱] 的意思。

組牌

當 [1柱] 和 [2柱] 最頂層的絕對差值等於1的時候,把小的疊到大的上面去。


核心算法

有了前面的理解之後接下來是如何解題的算法,如果你把它看懂了可以嘗試實際去玩玩,我也建議實際玩過幾輪再開始寫,可以更深刻的理解。照著下面的規則走,可以走出最少步驟。

最少步數

最小步數是 2的N次方-1,如果是只玩3層那就是 2的三次方-1=7,依此類推。
知道最多走幾步,也就是什麼時候結束,這可以用來設置迴圈上限。

條件

總共就分3個條件走,其中只要有任一個條件成立,移動完畢,就回頭重第一個條件重新跑過。
  1. 發牌
  2. 組牌
  3. 處理1柱和2柱
前兩個很容易,只要注意有沒有採到移動的規則就好。
第三個比較麻煩一點以下詳細說明
先知道當前1柱和2柱最層的大小,兩個大小的差值是基數還有偶數
基本這個數會大於1因為步驟2組起來了,但也有等於1的時候 (如底下實例中的第[10]步)
發生在組牌的時候正好踩到移動的限制,重複上一步驟。
如果差值是奇數
  • 把1柱和2柱中,小的那個收回0柱。
  • 如果上面步驟重上一步,複無法移動,則把大數收回。
如果差值是偶數
  • 把小的疊到大數上
  • 如果上面步驟重複上一步,無法移動,則把大數收回。
就照這幾個條件一直走下去,可以破關了。

實際演示

這是跑出來的實際步驟,可以對照著看上面的規則。
[0] 4, 3, 2, 1,
[1]
[2]
[step:0]--------init
---------------------------
[0] 4, 3, 2,
[1] 1,
[2]
[step:1]--------發牌
---------------------------
[0] 4, 3,
[1] 1,
[2] 2,
[step:2]--------發牌
---------------------------
[0] 4, 3,
[1]
[2] 2, 1,
[step:3]--------組牌
---------------------------
[0] 4,
[1] 3,
[2] 2, 1,
[step:4]--------發牌
---------------------------
[0] 4, 1,
[1] 3,
[2] 2,
[step:5]--------牌值差雙
---------------------------
[0] 4, 1,
[1] 3, 2,
[2]
[step:6]--------組牌
---------------------------
[0] 4,
[1] 3, 2, 1,
[2]
[step:7]--------發牌
---------------------------
[0]
[1] 3, 2, 1,
[2] 4,
[step:8]--------發牌
---------------------------
[0]
[1] 3, 2,
[2] 4, 1,
[step:9]--------牌值差單
---------------------------
[0] 2,
[1] 3,
[2] 4, 1,
[step:10]--------牌值差單
---------------------------
[0] 2, 1,
[1] 3,
[2] 4,
[step:11]--------牌值差雙
---------------------------
[0] 2, 1,
[1]
[2] 4, 3,
[step:12]--------組牌
---------------------------
[0] 2,
[1] 1,
[2] 4, 3,
[step:13]--------發牌
---------------------------
[0]
[1] 1,
[2] 4, 3, 2,
[step:14]--------發牌
---------------------------
[0]
[1]
[2] 4, 3, 2, 1,
[step:15]--------組牌
---------------------------


程式碼解析

基本上就是把上面的文字寫成代碼而已,可以注意看if else的階層,判斷邏輯會比較清楚。
        for (int i = 0; i < step_min; ++i) {
            int step = i+1;
            // 發牌
            if (sent()) {
                print("發牌", step);
            // 組牌
            } else if (defrag()) {
                print("組牌", step);
            } else {
                int diff = abs(p[1] - p[2]);
                // 牌值差雙
                if (diff % 2 == 0 and adju_even()) {
                    print("牌值差雙", step);
                }
                // 牌值差單
                else if (diff % 2 == 1 and adju_odd()) {
                    print("牌值差單", step);
                } else {
                    throw "沒有動作";
                }
            }
        }
代碼可以參考我的github
https://github.com/hunandy14/Hanoi

2020年7月23日 星期四

Dmitrirender 升級Win10 授權毀壞

Dmitrirender 升級 Win10 授權毀壞

這次我踩的坑是更新了 Win10 2004 然後授權就炸了…
弄好好久,最後是搞定了,也趁著這次機會詳細問了授權相關的規定。
我這次的狀況是莫名其妙炸了,寄信的給作者一來一回弄了好久,因為他也不知道什麼狀況只是看著我的報告跟我說,你必須移除虛擬機才可以幫你修復,但是我…就沒有裝呀。
經過各種嘗試,微軟內建的 ubuntu、沙盒 之類的有一點關聯的都刪除了,還是最不行。
最後是做完上述動作之後還跑到 UEFI裡面 關掉虛擬機的選項才好的。
之後再執行作者給的登錄檔就可以重新註冊了。

UEFI關閉虛擬機選項

進入UEFI(傳統叫法是BIOS)的方式跟傳統不一樣

進入BIOS步驟

在開始欄裡面按下重新啟動之前先按住SHIFT,然後關機,就會跳出選項,有一個難疑排解這個進入就有UEFI的選項了。
進去之後在UEFI找到這兩項關鍵字
  • intel virtualization technology
  • vt-d
把他關了就完事了。


關於授權的轉移

授權綁定的是方法是根據你的硬體來綁定的,啟動的當下會收集的你的硬體相關資訊並記錄到伺服器。

授權失效

如果硬體損壞,這包含 主機板、CPU、硬碟 等等其中一個損壞的話,那麼將永久失去授權,你只能再買一個了。(這個盜版的機制有點87)

授權轉移

如果是想更換設備,那麼你得先打開原本的機器,安裝 dmitrirender 並打開金鑰管理員
然後下一步到底就完成反激活了
反激活之後就會恢復到一開始剛買的時候,可以任意註冊到別的電腦,最多只能反激活20次。如果反激活之後序號被別人註冊走,那妳的授權就沒了,序號謹慎保管。


登錄檔內容

其實只有兩行打上來保存。
移除登錄檔會一併移除錯誤信息,沒錯誤信息可能會連作者都沒辦法救援,建議有問題先連絡作者。或者移除前先備份一下登錄檔。
Windows Registry Editor Version 5.00
[-HKEY_CURRENT_USER\Software\DmitriRender\Keys]

2020年7月20日 星期一

Win10 2004 新版 微軟新注音 不好用如何切回舊版

Win10 2004 新版 微軟新注音 不好用如何切回舊版

新版的微軟注音打字的游標不再是游標而是把最後一個字變黑框,用起來蠻不習慣了,不過也優點是選字的框框變得比較好看一些了,不過這些燈不是我遇到的主要問題。
最大的問題日文輸入法預設居然是英文的,還不能給使用者自訂,這樣我每次切過去要多按一次ALT+~ 把他切回片假名模式,煩呀乾脆改回來了。

切回舊版IME輸入法

先到設定裡面
然後選擇一般
滾到最底下就有一個使用舊版微軟新注音

2020年7月8日 星期三

Google Meet Grid View 失效 無法看到全部的人

Google Meet Grid View 失效 無法看到全部的人

前幾周開始 Grid View 突然失效了,怎樣都不能看到全部的人,不知道是怎麼了,這個本身似乎也不是google開發的,而是第三方開發的擴充,原作者似乎沒有空閒可以修復,問題反饋積了一大堆,詳細可以看這裡。
然後最近幾天終於有人看不下去做了修正版本了
使用方式很簡單先到擴充元件裡面
找到原本的 Google Meet Grid View 把他移除或是暫時關閉,然後安裝新的 Google Meet Grid View (fix) 就可以了。

bug

不過使用上有個小問題是,固定視窗有bug,主持人共享畫面的時候如果要釘選其他人的視窗會沒有反應。但是幾比起看不到大家更是困擾呢,原作者還沒更新之前先這樣撐著用吧。

2020年7月5日 星期日

筆電 3.5mm 插入耳麥之後 沒辦法使用麥克風

筆電 3.5mm 插入耳麥之後 沒辦法使用麥克風

我的筆電是華碩的 UX533FD 配置有3環的耳麥孔,不過不知道為什麼插入耳機的時候聲音一樣從喇叭出來,根本沒有切換到耳機上。
還有另一種情況是,明明上筆電上孔是三環的耳麥接孔,但是接上去之後麥克風就是沒聲音,依然從電腦內建的麥克風收音,都可以解決

如何手動切換耳機

先按一下你的開始按鈕然後搜尋 Realtek Audio Console 就可以找到他的驅動程式。
打開之後介面很空虛,就那幾個選項
依照所框的地方點選進階,然後就有選單可以選擇
改過之後就正常有聲音摟。
耳麥耳機的差別就如同字面上意思,如果還是不知道怎麼分別就看差頭有幾個環
  • 耳機的環只有2個
  • 耳麥會有三個環




為什麼會無法自動切換

主要是因為預設的自動切換是耳麥,如果你插耳機進去就什麼反應也沒有,這邊改過一次之後拔插就正常了。

2020年5月27日 星期三

Sony 手機省電方法 禁止背景程式執行

Sony 手機省電方法 禁止背景程式執行

本篇說明使用的作業系統版本為 Android 10
手機會太耗電不外乎就是應用程式裝太多了,有些應用程式自己會偷偷在背景不斷同步更新資料,看不到也不知道發生什麼事情了。好在現在安卓的版本已經可以管控了,分別會介紹SONY特有的白名單方式(關閉螢幕的狀態下只有允許的應用程式可以在背景同步),還有所有手機通用的黑名單模式(禁止特定程序在背景同步)。

背景檢查

這個功能要先開啟開發人員選項才有。
打開選項之後最下面的關於手機,進去之後在滑到最下面的版本號碼,對著這個點個3~5次就打開了。
然後回到設定的最上方有個搜尋,直接搜尋背景檢查,進去之後就可以直接控管了

黑名單模式

直接禁止應用程序在背景執行,長按應用程式圖示,然後選擇應用程式資訊進去,有些應用程式長按有功能,只會剩小圖示而不會有應用程式資訊字樣。
進去之後先按進階,打開完整選單,然後選擇電池,進去之後有個背景活動限制
這個點了之後就不會在背景執行了,有些應用程式不是很重要的就關掉吧。


SONY的白名單模式

SONY的省電模式STAMINA啟動之後會自動限制在螢幕關閉的時候禁止使用網絡,也就是可能會遇到的情況是把手機解鎖打開之後,才忽然收到一堆訊息。
這是預設的功能可以省不少電力,在通過設置白名單的方式讓特定應用程式,比如說LINE之類的,一般使用上也只有這些程式需要保持連線而已,可以讓用最省電力保持通訊。
首先從上拉選單打開 STAMINA 模式,或是到 設定->電池->STAMINA 這裡也可以打開。
設定->電池->STAMINA等級 可以設置省電的等級,如果選用待機模式動畫會變得卡卡的。
然後就完成第一步驟了,再來是設定那些應用程式例外。
進入設定之後直接在最上方搜尋 省電功能
從上方的未套用最佳化設定點一下,下拉選單選擇所有應用程式,然後再按右上角的那個小圖示,可以搜尋應用程式名字。
搜尋到之後點一下就可以設置了

2020年4月9日 星期四

2021新版 OBS 筆電 擷取螢幕 黑畫面 解決方法

2021新版 OBS 筆電 擷取螢幕 黑畫面 解決方法

先說答案,應該是Win10在搞事導致NVIDIA控制面板無法控制OBS要在外顯還是內顯執行。預設OBS在外顯執行,而螢幕預設為了省電是在內顯執行,進而導致無法擷取。
解決方案,到Win10內建的設置裡把OBS調整成省電模式,也就是在內顯執行就解決了。這是Win10-1909的解決方案,其他舊方法失效了。

調整Win10內建設置OBS為省電模式

桌面按右鍵打開顯示器設定
然後點選圖形設定
進來之後新增一下OBS,預設位置我幫你複製好了在這裡
C:\Program Files\obs-studio\bin\64bit
ok然後我們把它改成省電模式吧
這裡看一下
然後重新啟動你的OBS就可以看到擷取成功了。
到這邊就結束了,底下補充一些小知識。


怎麼看顯示器是跑內顯還是外顯

在顯示器的地方按進階顯示器
就可以查看當前顯示器是用什麼在跑
部分型號的筆電預設外接螢幕是用外顯跑,這時候就要回頭去把OBS設定成效能模式才能擷取到外接螢幕的影像。

如何查看程式是否在外顯跑

除了顯示之外還有一個問題是,遊戲擷取或是視窗節的時候,那個被截取的程式也要跟OBS在同一張卡在執行才可以。
也就是說用遊戲擷取的時候,擷取不不到影像的話,你得把OBS條回去效能模式才行。
NVIDIA內建有可以觀看那些程式在GPU上跑,這可以從設定內開出來。
然後到右下角查看,會有一個圖示跑出來,點開就有了。

如何強制程序在外顯上執行

剛剛提到的Win10的設定是一個方法,還有一個就是到NV的設置內。
這裡可以設置成高效能,就是在外顯上跑。
OBS比較特別,不管你怎麼設置都是在外顯跑,只有到Win10內設置才有效。
坑了我好多時間…


其他

這個解決方法其實官方有給,只是幹嘛不在下載的地方寫的明顯點QQQQ
https://obsproject.com/forum/threads/laptop-black-screen-when-capturing-read-here-first.5965/
巴哈也有一篇討論文章,有人挖出來,我也是從這邊注意到的感謝。
https://forum.gamer.com.tw/C.php?bsn=60030&snA=541106