贪心 openjudge特殊密码锁

探讨一种特殊二进制密码锁的解锁算法,通过分析按钮状态变化规律,提出了解决方案并给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总时间限制: 
1000ms 
内存限制: 
1024kB
描述

有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。

然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。

当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。

输入
两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
输出
至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
样例输入
011
000
样例输出
1

啊,亏我做了这么多的贪心题了,这道题竟然想不出来,可恶啊……

于是去网上看了题解,然后又是一脸蒙蔽,又去找证明。。。

先说贪心:讨论两种情况,第1个按钮按不按,然后对于后面的按钮i,如果i不是目标状态,就按下i+1

思路有点像模拟啊

然后是证明:

对于每一个与目标状态不符的按钮,我们的选择是要么按它本身,要么按与它相邻的按钮,而连续两次改变这个按钮相当于没改变,因此不会存在同一个按钮按两次的情况

所以,考虑是否按第1个按钮,如果第一个按钮的状态确定了,那么后一个按钮按与不按也就确定了,可以类推下去。然后根据前面不会存在同一个按钮按两次的情况,当然是不能往回按的

我曾疑惑这里为什么要讨论是否要按第1个按钮的情况,但是需要讨论的,给出一个理由,按第1个按钮,会使第1,2两个按钮都发生变化,如果第1个按钮是不匹配的,你按了

自然没有问题,而第2个按钮你就不能按了,而如果第1个按钮时匹配的,你按了,就意味着你必须要按第2个按钮,而着又会导致第3个按钮改变,所以要分情况讨论

好了,姑且就这样吧,我是再不能了

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>

const int MAXN=35;
const int inf=0x3f3f3f3f;
using namespace std;
char s1[MAXN],s2[MAXN],temp[MAXN];
int len;

inline void change(int i){
    temp[i]=temp[i]=='0'?'1':'0';
}
int solve1(){//!第一个按钮不按
    int ans=0; strcpy(temp,s1);
    for(int i=1;i<len;i++)
        if(temp[i-1]!=s2[i-1])
            change(i-1),change(i),change(i+1),ans++;
    for(int i=0;i<len;i++)
        if(temp[i]!=s2[i]) return inf;
    return ans;
}
int solve2(){//!第一个按钮按
    int ans=0; strcpy(temp,s1);
    change(0); change(1); ans++;
    for(int i=1;i<len;i++)
        if(temp[i-1]!=s2[i-1])
            change(i-1),change(i),change(i+1),ans++;
    for(int i=0;i<len;i++)
        if(temp[i]!=s2[i]) return inf;
    return ans;
}
int main()
{
    scanf("%s%s",s1,s2); len=strlen(s1);
    int ans=min(solve1(),solve2());
    if(ans==inf) printf("impossible");
    else printf("%d",ans);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值