OpenJudge 8469 特殊密碼鎖

2021-07-27 19:37:23 字數 1847 閱讀 7785

中國mooc網,程式設計與演算法(二)第一周作業1 

總時間限制: 1000ms 記憶體限制: 1024kb

有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成(n<30),按鈕有凹/凸兩種狀態,用手按按鈕會改變其狀態。

然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙個按鈕。

當前密碼鎖狀態已知,需要解決的問題是,你至少需要按多少次按鈕,才能將密碼鎖轉變為所期望的目標狀態。

兩行,給出兩個由0、1組成的等長字串,表示當前/目標密碼鎖狀態,其中0代表凹,1代表凸。

至少需要進行的按按鈕操作次數,如果無法實現轉變,則輸出impossible。

011 

000

1

首先思考列舉法,每個按鈕有2種狀態,但是最多可能有30個燈,因此狀態有2^30之多,窮舉一定會超時。

重點1

乙個燈如果按了第二下,就會抵消上一次按下所產生的影響。因此,乙個燈只有按或者不按兩種情況,不存在乙個燈要開關多次的情況。

例如八個燈 00000000 

按1後 11000000 

按3後 10110000 

按1後 01110000 

這和八個燈 00000000 

只按一次3後 01110000 

是完全相同的情況

重點2

我們只需要考慮是否按下第乙個燈。因為如果第乙個燈的狀態被確定了,那麼是否按下第二個燈也就決定了(如果第乙個燈與期望不同,則按下,如果期望相同,則不按下)同理,第三個燈是否按下也唯一確定。

所以,本題只要分兩種情況:燈1被按下和沒有被按下 

之後使用for迴圈判斷別的燈是否需要按下即可 

當迴圈結束,若現在的燈況與答案相同,則輸出兩種方案中按鍵次數最少的,若不同,則impossible!

#include #include #include #include using namespace std;

// 列舉第乙個按鈕是否按下的兩種情況即可,對於指定的一種情況,後面的事情都是確定的

int orilock;

int lock;

int destlock;

inline void setbit(int& n, int i, int v)

else

n &= ~(1 << i); // 設定 n 的第 i 位為0;

}inline void flipbit(int &n, int i)

inline int getbit(int n, int i)

int main()

if (getbit(lock, i) != getbit(destlock, i))

curbutton = 1;

else

curbutton = 0;

} if (lock == destlock)

mintimes = min(mintimes, times);

if (mintimes == 1 << 30)

cout << " impossible" << endl;

else

cout << mintimes << endl;

} return 0;

}

OpenJudge 8469 特殊密碼鎖(貪心)

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

8469 特殊密碼鎖

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

8469 特殊密碼鎖

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