描述
有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
输入
两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
输出
至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
样例输入
011
000
样例输出
1
拿题思想:在读完一遍题时,感觉有点懵,但是在读完第二遍时,并在纸上演示了一下示列,发现这个解密码就是从左往右看,如果看的当前位不是,那么就按动下一位,这样就能保证当前位为所需的目标码,然后依次类推下去,一个一个码的查看。
遇到问题:忘记区分第一位上的码,是否按的情况,因为第一位不按的情况下,只需一次往后读,按着走,都会改变周围的两个码,也就是按一次改变三个(除了最后一个)然后就是按第一个,会改变第一个和第二的,其他的与上相同。
最终解题步骤:
1)定义了三个char型数组,分别装当前码,目标码和按了第一位之后的当前码;
2)用枚举的方式依次验证如何将当前码的每一位改为目标码相对应的;
3)再验证是不按第一位和按了第一位能变成目标码,是其中一个能?还是都能?亦或是都不能?
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
char a[10000],b[10000],c[10000];
int main()
{
int step1=0,step2=0;
scanf("%s%s", a,b);
int l=strlen(a);
for(int i=0;i<l;i++)
c[i]=a[i];
step2++;
if(c[0]=='0')
c[0]='1';
else c[0]='0';
if(c[1]=='0')
c[1]='1';
else c[1]='0';
for(int i=0;i<l;i++)
{
if(c[i]!=b[i]&&i+1<l)
{
step2++;
c[i]=b[i];
if(c[i+1]=='0')
c[i+1]='1';
else c[i+1]='0';
if(c[i+2]=='0')
c[i+2]='1';
else c[i+2]='0';
}
}
for(int i=0;i<l;i++)
{
if(a[i]!=b[i]&&i+1<l)
{
step1++;
a[i]=b[i];
if(a[i+1]=='0')
a[i+1]='1';
else a[i+1]='0';
if(a[i+2]=='0')
a[i+2]='1';
else a[i+2]='0';
}
}
int d1=0,d2=0;
for(int i=0;i<l;i++)
{
if(c[i]!=b[i])
{
d2=1;
break;
}
}
for(int i=0;i<l;i++)
{
if(a[i]!=b[i])
{
d1=1;
break;
}
}
if(d1==0&&d2==0)
{
int s=min(step1,step2);
cout<<s<<endl;
}
else if(d1==0&&d2==1)
cout<<step1<<endl;
else if(d1==1&&d2==0)
cout<<step2<<endl;
else cout<<"impossible"<<endl;
return 0;
}