特殊密碼鎖深搜dfs

2021-10-01 15:35:32 字數 1525 閱讀 1645

按鈕有兩種情況 按和不按

按的話就將計數器加一

這個題很經典 還涉及到了深搜裡剪枝 即把那些剛開始遞迴就發現錯誤的 直接返回

在紙上畫畫會發現當遞迴到第k層的時候 第k-2層的資料是永遠不會在這個枝上發生變化的

一定要好搞懂第56行 為啥好要改回來

因為啊 不是有兩種情況麼 就先當作這個鍵按下去 那麼按下去不就要計數器加一 然後鍵再反轉麼

可當第二次以沒按下去的情況試試的時候 不應該保持原來嗎 但計數器已經是加過了 鍵也已經反轉了 所以要在上面再減回來 反轉回來

注釋很詳細

#include

#include

using

namespace std;

void

dfs(

int k)

;int n, ans =

100, js;

//給ans乙個較大的值 因為以後有按多少次都不行的情況 所以用ans來判斷

bool a[35]

, b[35]

;//a是初始的值 b是目標值

intmain()

dfs(1)

;//if(ans !=

100)

cout << ans;

else

//如果還是100就沒有發生改變

cout <<

"impossible"

;return0;

}void

dfs(

int k)

ans =

min(ans, js)

;return;}

if(k >3&&

(a[k -2]

!= b[k -2]

))return

;//這個就是減枝 如果不加這個會超時

//在紙上畫畫會發現 到了k比3大的時候,k-2位上的數字是永遠也不會發生變化的

//下面分兩中情況

//1.這個鍵按下了

js++

;//按下的話就把按下的次數記上

a[k]

=!a[k]

, a[k -1]

=!a[k -1]

, a[k +1]

=!a[k +1]

;//反轉 k+1超是美事的因為咱們開的陣列夠大 超了的話後來判斷又不影響

dfs(k +1)

;//假如這個按下 就用這個接著判斷下面的

//如果是沒按呢 上面的分支返回到這的時候就要試試沒按的情況了

//因為js a都是全域性變數 剛剛已經對他們改變了

//所以還要變回來 因為他們兩個在當前分支是平等的

js--

; a[k]

=!a[k]

, a[k -1]

=!a[k -1]

, a[k +1]

=!a[k +1]

;dfs

(k +1)

;//按著這個鍵沒按的情況再往下分支

}

特殊密碼鎖

有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成 n 30 按鈕有凹 凸兩種狀態,用手按按鈕會改變其狀態。然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙個按鈕。當前密碼鎖狀態已知,需要解決的問題是,你至少需要按...

特殊密碼鎖

總時間限制 1000ms 記憶體限制 1024kb 描述 有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成 n 30 按鈕有凹 凸兩種狀態,用手按按鈕會改變其狀態。然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙...

特殊密碼鎖

例題四 特殊密碼鎖 描述有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成 n 30 按鈕有凹 凸兩種狀態,用手按按鈕會改變其狀態。然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙個按鈕。當前密碼鎖狀態已知,需要解...