中國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 按鈕有凹 凸兩種狀態,用手按按鈕會改變其狀態。然而讓人頭疼的是,當你按乙個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的乙個...