POJ 8496 特殊密码锁

特殊密码锁

问题描述:

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

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

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

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

解题思路:本来还想从奇偶方面入手,但是发现自己想的太简单了,本来想根据0,1数量,从奇偶方面判断,后来试一试才发现,情况根本没那么简单。百度了一下,才知道贪心算法。先保证最后一位前面的数字都相同,不停按下按钮,如果到最后,最后一位也相同,则输出按下按钮的次数,否则输出Impossible。需要注意的一点就是,在前两个按钮不同的时候,是按第一个按钮,还是按第二个按钮,这个问题需要加以判断,若两种都可行,则最后需要输出按下次数最小的数值。

import java.util.Arrays;
import java.util.Scanner;

public class SpecialCodedLock {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);

        char[] s = in.nextLine().toCharArray();
        char[] goal = in.nextLine().toCharArray();

        int count = 0;
        int count_2 = 0;
        int result = -1;

        //第一种情况:前两个按钮不同,按下第二个按钮
        char[] temp = Arrays.copyOf(s, s.length);

        for(int i = 1; i < goal.length; i++) {
            if(temp[i - 1] != goal[i - 1]) {
                push(temp, i);
                count++;
            }
        }

        //判断字符数组s与goal的最后一个字符是否相等
        if(temp[temp.length - 1] == goal[goal.length - 1]) {
            result = 1;
        }
        else {
            count = (int) 1e9;
        }

        temp = Arrays.copyOf(s, s.length);
        //第二种情况:前两个按钮不同,按下第一个按钮
        if(temp[0] != goal[0]) {
            temp[0] = temp[0] == '0' ? '1' : '0';
            if(1 < s.length)
                temp[1] = temp[1] == '0' ? '1' : '0';
            count_2++;
        }

        for(int i = 2; i < goal.length; i++) {
            if(temp[i - 1] != goal[i - 1]) {
                push(temp, i);
                count_2++;
            }
        }

        if(temp[temp.length - 1] == goal[goal.length - 1]) {
            result = 1;
        }
        else {
            count_2 = (int) 1e9;
        }


        //如果result等于-1,则无法转变为目标字符串
        if(result != -1) {
            System.out.println(count > count_2 ? count_2 : count);
        }
        else {
            System.out.println("impossible");
        }
    }

    //改变按下按钮的前后及自身的值
    public static void push(char[] temp, int i) {
        temp[i] = temp[i] == '0' ? '1' : '0';
        temp[i - 1] = temp[i - 1] == '0' ? '1' : '0';
        if(i + 1 < temp.length)
            temp[i + 1] = temp[i + 1] == '0' ? '1' : '0';
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值