特殊密碼鎖
阿新 • • 發佈:2018-11-16
總時間限制: 1000ms 記憶體限制: 1024kB
描述
有一種特殊的二進位制密碼鎖,由n個相連的按鈕組成(n<30),按鈕有凹/凸兩種狀態,用手按按鈕會改變其狀態。
然而讓人頭疼的是,當你按一個按鈕時,跟它相鄰的兩個按鈕狀態也會反轉。當然,如果你按的是最左或者最右邊的按鈕,該按鈕只會影響到跟它相鄰的一個按鈕。
當前密碼鎖狀態已知,需要解決的問題是,你至少需要按多少次按鈕,才能將密碼鎖轉變為所期望的目標狀態。
輸入
兩行,給出兩個由0、1組成的等長字串,表示當前/目標密碼鎖狀態,其中0代表凹,1代表凸。
輸出
至少需要進行的按按鈕操作次數,如果無法實現轉變,則輸出impossible。
樣例輸入
011
000
樣例輸出
1
啊啊啊在11:00pm前兩分鐘AC了,好開心啊可以不用熬夜了,程式設計能力不好的我折騰一晚上了,一直在找錯,一個很好的檢查哪一步錯誤的辦法是輸出中間結果。我知道我的程式碼有點囉嗦,按不按第一個鎖兩種情況很多程式碼類似,但是我合併不好。
還有,要重視位運算。晚安~
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int setbit(int &n,int i,int v){//將n的第i位設定為v if(v) n|=(1<<i); else n&=~(1<<i); } int getbit(int n,int i){//取出n的第i位 return (n>>i)&1; } int flipbit(int &n,int i){//將n的第i位取反 n^=(1<<i); } int orilock=0;//原始鎖開關情況 int lock=0;//過程中鎖開關情況 int result=0; //結果鎖開關情況 int main(){ char line[40]; cin>>line; int times1=0,times2=0; int mintimes=0; int n=strlen(line); for(int i=0;i<n;++i) setbit(orilock,i,line[i]-'0');//將原始情況存入 cin>>line; for(int i=0;i<n;++i) setbit(result,i,line[i]-'0');//將結果存入 for(int p=0;p<2;p++){//列舉第一個密碼按還是不按 lock=orilock;//按下第一個鎖 if(!p){//按下第一個 times1++; flipbit(lock,0); flipbit(lock,1); for(int i=1;i<n;i++){ if(getbit(lock,i-1)!=getbit(result,i-1)){ times1++; flipbit(lock,i-1); flipbit(lock,i); if(i<n-1) flipbit(lock,i+1); } } if(lock!= result) times1=100; } else if(p){//不按第一個 for(int i=1;i<n;i++) if(getbit(lock,i-1) !=getbit(result,i-1)){ times2++; flipbit(lock,i-1); flipbit(lock,i); if(i<n-1) flipbit(lock,i+1); } if(lock!= result) times2=100; } } mintimes=min(times1,times2); if(mintimes==100){ cout<<"impossible"<<endl; return 0; } cout<<mintimes<<endl; return 0; }