华为OD机考题目《解密犯罪时间》200分题目


最近在百度文库上找到这么一道华为OD的机考题目,题目链接:


个人感觉这道题很有意思,就试着做一下。


文库中提供了一份代码。

我自己做的,肯定不是最优解,但我觉得没啥问题。
这道题就四个数排列组合,且可选项也不多,暴力破解不会超时。

C++版:
#include <iostream>
using namespace std;
int main() {
    string str;
    cin >> str;
    //搞个数组把字符串解析成单个的数字,注意跳过冒号。(题目保证输入合法,不用单独校验长度不够、缺少冒号等情况)
    int num[4] = { char(str[0] - '0'),char(str[1] - '0'),char(str[3] - '0'),char(str[4] - '0')};

    //把时间转为分钟。
    int inTime = (num[0] * 10 + num[1]) * 60 + (num[2] * 10 + num[3]);
    int minTimeDiff = 24 * 60 * 60;
    int minIndex[4] = { 0 };

    //暴力破解,找出所有排列组合
    for (int index0 = 0; index0 < sizeof(num) / sizeof(int); index0++) {
        //因为最大是 23:59,所以首位大于2则直接排除
        if (num[index0] > 2) continue;
        for (int index1 = 0; index1 < sizeof(num) / sizeof(int); index1++) {
            //当小时 首位是2时,第二位最大是3。
            if (num[index0] == 2 && num[index1] > 3) continue;
            for (int index2 = 0; index2 < sizeof(num) / sizeof(int); index2++) {
                //分钟位只能是0-5,不可能出现6-9
                if (num[index2] > 5) continue;
                for (int index3 = 0; index3 < sizeof(num) / sizeof(int); index3++) {
                    int newTime = (num[index0] * 10 + num[index1]) * 60 + (num[index2] * 10 + num[index3]);
                    if (newTime < inTime) {
                        //如果比当前时间还要早,则把它算到下一天去。
                        newTime += 24 * 60 * 60;
                    }
                    else if (newTime == inTime) {
                        continue;
                    }
                    //找出最小的时刻。
                    if (newTime - inTime < minTimeDiff) {
                        minTimeDiff = newTime - inTime;
                        minIndex[0] = index0;
                        minIndex[1] = index1;
                        minIndex[2] = index2;
                        minIndex[3] = index3;
                    }
                }
            }
        }
    }
    cout << num[minIndex[0]] << num[minIndex[1]] << ":" << num[minIndex[2]] << num[minIndex[3]] << endl;
    return 0;
}


JAVA:
import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
    // write your code here
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        char[] key = new char[4];
        key[0]=input.charAt(0);
        key[1]=input.charAt(1);
        key[2]=input.charAt(3);
        key[3]=input.charAt(4);
        String result = "";
        int min=getTime('2','4','0','0');
        int tFlag = getTime(key[0],key[1],key[2],key[3]);
        for (int i = 0; i < 4; i++) {
            if(key[i]>'2')  continue;
            char[] team = new char[4];
            team[0]=key[i];
            for (int j = 0; j < 4; j++) {
                if(key[i]=='2' && key[j]>'3')   continue;
                team[1]=key[j];
                for (int k = 0; k < 4; k++) {
                    if(key[k]>'6')  continue;
                    team[2]=key[k];
                    for (int l = 0; l < 4; l++) {
 
                        team[3]=key[l];
                        int t = getTime(team[0],team[1],team[2],team[3]);
                        int curTime;
                        if(t>tFlag){
                            curTime = t-tFlag;
                        }else {
                            curTime = getTime('2','4','0','0')-tFlag+t;
                        }
                        if(min>curTime){
                            min=curTime;
                            StringBuilder e = new StringBuilder();
                            e.append(team[0]);
                            e.append(team[1]);
                            e.append(':');
                            e.append(team[2]);
                            e.append(team[3]);
                            result=e.toString();
                        }
                    }
                }
            }
        }
        if(result.equals("")){
            System.out.println(input);
        }else {
            System.out.println(result);
        }
 
    }
    public static int getTime(int h1,int h2,int s1,int s2){
        h1-='0';
        h2-='0';
        s1-='0';
        s2-='0';
        return h1*10*60+h2*60+s1*10+s2;
    }
 
}



PYTHON:
import time
import datetime
import re
ti = input()
num_list = re.findall('[0-9]',ti)
today = time.strftime('%Y-%m-%d',time.localtime())
strs = today+' '+ti
pass_time = datetime.datetime.strptime(strs,'%Y-%m-%d %H:%M')
 
while True:
    pass_time = pass_time+datetime.timedelta(minutes=1)
    h_m = pass_time.strftime('%H:%M')
    hm_list = re.findall('[0-9]',h_m)
    c = 0
    for i in hm_list:
        if i in num_list:
            c = c+1
    if c == len(hm_list):
        break
print(h_m)
            



其他语言的代码,大家可以自行考虑一下。







全部评论
前面发的有错误,删掉重发,并加上注释~执行时间远小于1s内。 思路是排列组合,以 12:24 为例,拆成[1,2,4] ,对列表中这三个数从小到大进行排列组合,分别是11:11/11:12/11:21 这样子类推,然后大于 12:24 的时间便可以返回,否则返回最小的时间组合
2 回复 分享
发布于 2022-06-22 11:14
使用回溯算法+剪枝 的做法实现了下,供参考
点赞 回复 分享
发布于 2022-08-24 14:21 陕西
JavaScript版本
1 回复 分享
发布于 2022-09-20 09:06 重庆
var g [4]int var nums [4]int var minDIffMinute int func nextTime(s string) string { minDIffMinute = 24*60 strs := strings.Split(s, ":") hour, _ := strconv.Atoi(strs[0]) minute, _ := strconv.Atoi(strs[1]) minute = hour*60+minute nums = [4]int{int(strs[0][0])-'0&(30533)#39;, int(strs[0][1])-'0&(30533)#39;, int(strs[1][0])-'0&(30533)#39;, int(strs[1][1])-'0&(30533)#39;} dfs(0, 4, minute) resMinute:=minute+minDIffMinute if resMinute > 24*60{ resMinute -= 24*60 } hour, minute = resMinute/60,resMinute%60 return strconv.Itoa(hour)+":"+strconv.Itoa(minute) } func dfs(start int, n int,  minute int) { if n == start { if g[0] >2 ||  g[1] > 4 ||  g[2] > 5 ||  g[1] > 9{ return } curMinute := 60*(10*g[0]+g[1])+10*g[2]+g[3] if curMinute < minute{ curMinute+=24*60 } if curMinute==minute{ return } if minDIffMinute> curMinute-minute { minDIffMinute = curMinute-minute } return } for i:=0;i<4;i++{ g[start] = nums[i] dfs(start+1, n, minute) } } // 12:21
点赞 回复 分享
发布于 2022-08-18 12:05 陕西
您好,我是计算产品线某LAB的,有没有兴趣参与一下全栈AI大模型的性能加速研究。在我们部门你可以学习到【AI算法、AI系统、神经网络搜索、联邦学习、异步训练】等一系列先进技术。从训练到推理,从单卡到分布式,大到大模型,小到一个个算子,甚至是指令流,都有探索和研究。所以目前正在大量招人,有兴趣的话麻烦发个简历给我,感谢。【特别说明】:我们LAB不怎么加班,周三周五可以五点半下班,其他时候八点半下班。【地点】:杭州,北京,深圳
点赞 回复 分享
发布于 2022-07-21 14:39
写一个核心函数,主要是剪枝, public static void getNear(int[] num, String cur, String time, int depth, List<String> res) {         if(cur.length() == 4) {             if(!cur.equals(time)) {                 res.add(cur);             }             return;         }         for(int i = 0; i < num.length; i++) {             if(depth == 0 && num[i] > 2) {                 continue;             }             if(depth == 1 && cur.charAt(0) == '2' && num[i] > 3 ) {                 continue;             }             if(depth == 2 && num[i] > 5) {                 continue;             }             getNear(num, cur + String.valueOf(num[i]), time,depth + 1, res);         }     }
点赞 回复 分享
发布于 2022-07-15 01:07
想问下lz,西安od d3 16+4大概什么水平
点赞 回复 分享
发布于 2022-05-28 18:32
最近咋迷上做题了呢?
点赞 回复 分享
发布于 2022-05-26 11:44

相关推荐

评论
6
1
分享

创作者周榜

更多
牛客网
牛客企业服务