描述
有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成(n<30),按鈕有凹/凸兩種狀態,用手按按鈕會改變其狀態。
然而讓人頭疼的是,當你按一個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的一個按鈕。
當前密碼鎖狀態已知,需要解決的問題是,你至少需要按多少次按鈕,才能將密碼鎖轉變為所期望的目標狀態。
輸入兩行,給出兩個由0、1組成的等長字串,表示當前/目標密碼鎖狀態,其中0代表凹,1代表凸。輸出至少需要進行的按按鈕操作次數,如果無法實現轉變,則輸出impossible。樣例輸入
011 000
樣例輸出
1
---------------------------------------------------------------------------------------------------
[2016年青島市程式設計競賽]第二題
我竟然沒看出是貪心,傻乎乎的寫搜尋還在最後把set判重刪了,唉........................
對於第一個按鈕,如果不同,要不按第一個,要不按第二個;
從左往右考慮,對於每一個不同的按鈕,都按下一個,這樣不影響前面的狀態
// // main.cpp // openjudge特殊密碼鎖 // // Created by abc on 16/8/20. // Copyright © 2016年 abc. All rights reserved. // #include <iostream> #include <string> #include <algorithm> using namespace std; string s,t,fin; int tmp=0,ans=1e9,n; inline void flip(int i){ s[i-1]=s[i-1]=='1'?'0':'1'; s[i]=s[i]=='1'?'0':'1'; if(i+1<n) s[i+1]=s[i+1]=='1'?'0':'1'; } int main(int argc, const char * argv[]) { cin>>s>>fin;t=s; n=s.size(); for(int i=1;i<n;i++) if(s[i-1]!=fin[i-1]){ flip(i); tmp++; } if(s[n-1]==fin[n-1]) ans=tmp; tmp=1; s=t; s[0]=s[0]=='1'?'0':'1'; s[1]=s[1]=='1'?'0':'1'; for(int i=1;i<n;i++) if(s[i-1]!=fin[i-1]){ flip(i); tmp++; } if(s[n-1]==fin[n-1]) ans=min(ans,tmp); if(ans==1e9) cout<<"impossible"; else cout<<ans; return 0; }