代码拉取完成,页面将自动刷新
有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。
然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。
当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
011
000
1
8469
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
void SetBit(int &c, int i, int v)
{
if (v)
{
c |= (1<<i);
}
else
c &= ~(1<<i);
}
/* 将开关转换为实际掩码
*/
int act2mask(int act, int n)
{
int result = 0;
for (int i=0; i<n; i++)
{
if (act&(1<<i))
{
result ^= (1<<i);
if (i>0)
result ^= (1<<(i-1));
if (i<n-1)
result ^= (1<<(i+1));
}
}
return result;
}
/* change:
返回按钮个数
参数:
from: 原锁
to: 变化后的锁
act: 最后两位
n: 总位数
注意:运算符的优先级
*/
int change(int from, int to, int act, int n)
{
int count=0;
if (((from^act2mask(act,n))&1) != (to&1))
return -1;
for (int i=1;i<n-1;i++)
{
SetBit(act, i+1, ((from^act2mask(act,n)^to)>>i)&1);
}
if ((from^act2mask(act,n))==to)
{
for (int i=0;i<n;i++)
if (act&(1<<i))
count++;
return count;
}
else
return -1;
}
int main()
{
char a[32], b[32];
int from=0, to=0, n;
int found = 0;
scanf("%s%s", a, b);
n=strlen(a);
for (int i=0;i<n;i++)
{
from = from * 2 + a[i]-'0';
to = to * 2 + b[i]-'0';
}
for (int i=0;i<3; i++)
{
int count;
if ((count=change(from, to, i, n))>=0)
{
printf("%d\n", count);
found = 1;
break;
}
}
if (!found)
printf("impossible\n");
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。