按鈕有兩種情況 按和不按注釋很詳細按的話就將計數器加一
這個題很經典 還涉及到了深搜裡剪枝 即把那些剛開始遞迴就發現錯誤的 直接返回
在紙上畫畫會發現當遞迴到第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 按鈕有凹 凸兩種狀態,用手按按鈕會改變其狀態。然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙個按鈕。當前密碼鎖狀態已知,需要解...