算法-解密犯罪时间(回溯求全排列

要求的时间需要晚于当前时间且和当前时间最近。时间串里一共四个数字字符,做全排列即可,使用到回溯算法。把时间串里的“:”剔除后,做回溯爆搜,每取4个字符就判断一次:1.作为时间串是否合法;2.如果合法,反应到最终结果中去;

特殊处理1:当以输入时间串得不到更大的时间时,说明比当前时间更晚的是第二天的时间,又要求这个时间离当前时间最近,所以直接取能得到的最小时间即可。

特殊处理2:当输入“00:00”,“11:11”,“22:22”这些四个位置都相同的时间串时,答案是其本身,含义:第二天的同一时刻。

import java.util.*;
public class Main{
    public static List<Character> path=new ArrayList<>();
    public static int base,min=Integer.MAX_VALUE,diff=Integer.MAX_VALUE;
    public static String ans="",original,minStr="";

    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        String s=in.nextLine();
        String[] a=s.split(":");

        List<Character> list=new ArrayList<>();
        original=a[0]+a[1];
        char c=original.charAt(0);
        int flag=0;
        list.add(c);
        for(int i=1;i<4;i++){
            if(original.charAt(i)!=c){
                flag=1;
            }
            list.add(original.charAt(i));
        }
        if(flag==0){
            System.out.println(s);
            return;
        }
        base=toMinutes(original);
        dfs(list);
        if(ans.length()==0){
            ans=minStr;
        }
        ans=ans.substring(0,2)+":"+ans.substring(2,4);
        System.out.println(ans);
    }
    public static void dfs(List<Character> list){
        if(path.size()==4){
            String s="";
            for(char ch:path){
                s+=ch;  
            }
            if(!s.equals(original)&&check(s)){
                int v=toMinutes(s),d=Math.abs(v-base);
                // 维护一个最小值,当“没有大于base”发生时,作为最后的值
                if(v<min){
                    min=v;
                    minStr=s;
                }
                if(v>base&&d<diff){
                    ans=s;
                    diff=d;
                }
            }
            return;
        }
        for(int i=0;i<4;i++){
            path.add(list.get(i));
            dfs(list);
            path.remove(path.size()-1);
        }
    }
    public static int toMinutes(String s){
        int h=Integer.parseInt(s.substring(0,2)),m=Integer.parseInt(s.substring(2,4));
        return h*60+m;
    }
    public static boolean check(String s){
        int h=Integer.parseInt(s.substring(0,2)),m=Integer.parseInt(s.substring(2,4));
        return h>=0&&h<=23&&m>=0&&m<=59;        
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗=里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值