华为OD机试真题C卷-篇2

文章目录

  • 启动多任务排序
  • 有效子字符串
  • 最长子字符串的长度
  • 最长子字符串的长度(二)
  • 两个字符串间的最短路径问题
  • 生成Huffman树
  • 可以处理的最大任务
  • 中文分词模拟器
  • 手机App防沉迷系统
  • 根据IP查找城市
  • 文件缓存系统
  • 寻找最优的路测线路
  • Wonderland游乐园
  • 项目排期/最少交付时间
  • 灰度图存储
  • 精准核酸检测
  • 运输时间

启动多任务排序

  • A任务依赖B任务,执行时需要先执行B任务,完成后才可以执行A任务;
  • 若一个任务不依赖其他任务,则可以立即执行,多个同时执行的任务按照字母顺序A-Z排序;
  • 若B依赖A,C依赖A,D依赖B、C、E,则任务执行顺序为A、E、B、C、D;AE是同时执行且按照字母顺序;
    输入描述:
    多个任务的依赖关系;如A->B A依赖B,多组依赖关系用空格隔开
    输出描述:
    任务执行顺序,多个任务用空格隔开

示例1
输入:
A->B C->B
输出:
B A C

示例2
输入:
B->A C->A D->B D->C D->E
输出:
A E B C D

示例3
输入:
B->A E->A D->A E->D C->B F->B
输出:
A B D C E F

示例4
输入:
B->A C->A D->G E->F F->G
输出:
A G B C D F E

思路:

  • 迭代处理依赖关系列表,当没有依赖关系时(列表为空),所有的任务可以同时执行,只需按照字母顺序排序即可;
  • 每个依赖关系字符串使用 ‘->’ 分割出主动依赖的任务,被依赖的任务
    • 主动依赖的任务放入一个集合depending_tasks;
    • 被动依赖的任务放入一个集合depended_tasks;
    • 两个集合的并集为所有的任务(all_tasks 集合);
    • 两个集合的差集(depended_tasks - depending_tasks)为独立的任务,独立的任务可以立即执行,并按照字母顺序排序;
  • 将可以立即执行的任务排序后放入task_run_order列表,并重新过滤依赖关系列表(若依赖的任务已经执行,则删除该依赖关系)
  • 继续迭代处理剩余的依赖关系列表,直至其为空,此时剩余的任务(all_tasks - task_run_order)不再有依赖关系,可以同时执行,并按照字母顺序排序即可,最后加入task_run_order列表。
  • 返回task_run_order
# __author__ = "laufing"
from typing import List


class SortTask:
    def solution(self, dependent_relations: List[str]):
        # 迭代
        task_run_order = []
        pre_run_tasks = set()
        # 所有的任务
        all_tasks = set()

        while dependent_relations:
            # 主动依赖其他任务的任务
            depending_tasks = set()
            # 被依赖的任务
            depended_tasks = set()
            for relation in dependent_relations:
                # 任务分割 前者主动依赖  后者被动依赖
                task_a, task_b = relation.split("->")

                if task_a not in depending_tasks:
                    depending_tasks.add(task_a)
                if task_b not in depended_tasks:
                    depended_tasks.add(task_b)

            print("depending:", depending_tasks)
            print("depended:", depended_tasks)
            if not all_tasks:
                all_tasks = depending_tasks | depended_tasks
			if pre_run_tasks:
				task_run_order.extend(sorted(list(pre_run_tasks-depending_tasks)))
				pre_run_tasks.clear()
            # 获取不依赖其他任务的 任务(独立的)
            # 独立的任务可以立即执行(注意按字母顺序排序)
            independent_tasks = depended_tasks - depending_tasks
            task_run_order.extend(sorted(list(independent_tasks)))
            
            # 处理依赖关系
            temp_relations = []
            for relation in dependent_relations:
            	if relation[-1] in task_run_order:
            		pre_run_tasks.add(relation[0])
            	else:
            		temp_relations.append(relation)
			dependent_relations = temp_relations
        # 依赖关系解决完后,执行剩余的任务
        task_run_order.extend(sorted(list(all_tasks - set(task_run_order))))
		
		# 任务去重
		result = []
		for i in task_run_order:
			if i not in result:
				result.append(i)
        return result


if __name__ == '__main__':
    sort_task = SortTask()
    while True:
        try:
            # 输入
            lay_relations = input("lay:").strip().split()
            print("origin relations:", lay_relations)
            # 解决方案
            result = sort_task.solution(lay_relations)
            # 输出结果
            print(" ".join(result))
        except KeyboardInterrupt:
            break

 

有效子字符串

  • 输入两个字符串S、L, len(S)<=100, len(L)<=500000;
  • 判断S是否是L的有效子字符串;
  • 判断规则:S中的每个字符在L中存在,且保持与S中一致的顺序;
    输入描述:
    一行输入S
    一行输入L,只包含小写字母
    输出描述:
    S最后一个有效字符在L中的索引位置,无有效字符则输出-1

示例1
输入:
ace
abcde
输出:
4

示例2
输入:
fgh
abcde
输出:
-1

思路:

  • 索引遍历字符串S,依次在temp_l_str中查找 (find方法);
  • 使用valid_pos (元组)列表,存储S中每个字符在L中的位置,如[(‘a’, 0)];
  • 从L中每次找到的当前位置分片pre字符串,temp_l_str 两部分,迭代从temp_l_str继续查找S中的下一个字符,找到的索引位置+len(pre) ,然后存入valid_pos,未找到则继续下一次迭代;
  • 若valid_pos为空,则输出-1
  • 若valid_pos非空,则输出valid_pos[-1][1]
# __author__ = "laufing"


class ValidSubString:
    def solution(self, s_str, l_str):
        # S中字符的有效位置
        valid_pos = []
        s_str_length = len(s_str)
        # 前部分
        pre = ""
        # 后部分
        temp_l_str = l_str[:]
        for i in range(s_str_length):

            pos = temp_l_str.find(s_str[i])
            if pos != -1:  # 找到
                # 恢复在l_str中的位置
                pos = len(pre) + pos
                valid_pos.append((s_str[i], pos))
                # 重新分割
                pre = l_str[:pos+1]
                temp_l_str = l_str[pos+1:]

            if not temp_l_str:
                break
        if valid_pos:
            print(valid_pos[-1][1])
            return valid_pos[-1][1]

        print(-1)
        return -1


if __name__ == '__main__':
    valid_sub_str = ValidSubString()
    while True:
        try:
            s = input("s:").strip()
            l = input("l:").strip()
            result = valid_sub_str.solution(s, l)

        except KeyboardInterrupt:
            break

其他思路:

import functools
class TreeNode:
    def __init__(self, left, right, weight, height):
        self.left = left
        self.right = right
        self.weight = weight
        self.height = height
 
 
s_arr = input()
l_arr = input()
index1 = 0
index2 = 0
 
while (index1 < len(s_arr) and index2 < len(l_arr)) :
    if (s_arr[index1] == l_arr[index2]) :
        index1+=1
    
    index2+=1
 
if(index1 == len(s_arr)):
    print(index2 - 1)
else:
    print(-1)

最长子字符串的长度

  • 给一个字符串s, 它的首尾相连成一个环;
  • 在环中找出‘o’字符出现了偶数次的最长子串的长度;
    输入描述:
    小写字母组成的字符串
    输出描述
    一个整数

示例1
输入:
alolobo
输出:
6
说明,最长子串之一是‘alolob’,包含两个‘o’

示例2
输入:
looxdolx
输出:
7

示例3
输入:
bcbcbc
输出:
6

import functools
import sys
from collections import Counter
 
s = input()
s_slices = Counter(s)
num = s_slices.get("o",0)
print(len(s) - 1 if num % 2 else len(s))

 

最长子字符串的长度(二)

  • 在上一题的基础上,在环中找出l、o、x字符都出现了偶数次的最长子串的长度;
    示例1
    输入:
    alolobo
    输出:
    6
    说明, 最长子串之一alolobo,包含l/o各两个,x 是0个

示例2
输入:
bcbcbc
输出:
7

 
def findTheLongestSubstring(s) :
    dp = [[] for i in range(8)]
    dp[0].append(-1)
    pattern = 0
    res = 0
    for i in range(len(s)):
        if s[i] == 'l':
            pattern^= (1<<0)
        elif s[i] == 'o':
            pattern^= (1<<1)
        elif s[i] == 'x':
            pattern^= (1<<2)
        current = dp[pattern]
        current.append(i)
        #长度不能超过n
        while(True):
            if(current[-1] - current[0] <= len(s)/2):
                break
            current.pop(0)
        if(res < current[-1] - current[0]):
            res = current[-1] - current[0]
    return res
 
input_str = input()
print(findTheLongestSubstring(input_str+input_str))          

 

两个字符串间的最短路径问题

华为OD机试真题C卷-篇2_第1张图片
华为OD机试真题C卷-篇2_第2张图片
在这里插入图片描述


result = float('inf')
input_strs = input().split(" ")
str1 = input_strs[0]
str2 = input_strs[1]
n = len(str1)
m = len(str2)
 
visited = [[0 for i in range(m+2)] for j in range(n+2)]
lst = []
lst.append([-1, -1, 0])
while (True):
    if(len(lst)<=0) :
        print(result)
        break
    else :
        current = lst[0]
        lst.pop(0)
        if (current[0] +1 == n) :  
            if(current[2] - current[1] + m - 1 < result) :
                result = current[2] - current[1] + m - 1
            
            continue
        
        if (current[1] +1 == m) :  
            if(current[2] - current[0] + n - 1 < result) :
                result = current[2] - current[0] + n - 1
            
            continue
        
        if (str1[current[0]+1] == str2[current[1]+1]) : 
            if (visited[current[0] + 2][current[1]+2] == 0) :  
                visited[current[0] + 2][current[1]+2] = 1
                lst.append([current[0] + 1, current[1]+1, current[2] + 1]) 
            
        else :  
            if (visited[current[0] + 2][current[1]+1] == 0) : 
                visited[current[0] + 2][current[1]+1] = 1
                lst.append([current[0] + 1, current[1], current[2] + 1])  
            
            if (visited[current[0] + 1][current[1]+2] == 0) :  
                visited[current[0] + 1][current[1]+2] = 1
                lst.append([current[0], current[1]+1, current[2] + 1])  
                    
                          

 

生成Huffman树

华为OD机试真题C卷-篇2_第3张图片
华为OD机试真题C卷-篇2_第4张图片

import functools
result = []
n = int(input())
nums = [int(x) for x in input().split(" ")]
 
class TreeNode:
    def __init__(self, left, right, weight, height):
        self.left = left
        self.right = right
        self.weight = weight
        self.height = height
 
 
def dfs(node) :
    if(node.left is not None) :
        dfs(node.left)
    
    result.append(node.weight)
    if(node.right is not None) :
        dfs(node.right)
        
    
 
TreeNode_list = []
for i in range(n):
    TreeNode_list.append(TreeNode(None,None,nums[i],1))
 
def comp(o1,o2):
    if(o1.weight == o2.weight):
        if(o1.height - o2.height>0):
            return 1
        else:
            return -1
    
    if(o1.weight - o2.weight>0):
        return 1
    else:
        return -1
 
while (True):
    if(len(TreeNode_list) <= 1):
        break
    else :
        TreeNode_list = sorted(TreeNode_list, key=functools.cmp_to_key(comp))
        node1 = TreeNode_list[0]
        node2 = TreeNode_list[1]
        TreeNode_list.pop(0)
        TreeNode_list.pop(0)
        TreeNode_list.append(TreeNode(node1, node2, node1.weight + node2.weight, max(node1.height, node2.height) + 1))
    
 
 
dfs(TreeNode_list[0])
output_str = ""
for i in range(len(result)):
    output_str += str(result[i])
    if(i!=len(result)-1):
        output_str+=" "
print(output_str)
    
 

 

可以处理的最大任务

华为OD机试真题C卷-篇2_第5张图片
在这里插入图片描述

 
n = int(input())
tasks = []
for i in range(n):
    tasks.append([int(x) for x in input().split(" ")])
 
tasks = sorted(tasks, key=lambda x: -x[1])
 
queue = []
end_time = 100000
result = 0
i=0
while(True):
    if(i>=n):
        while (len(queue) > 0) :
            temp = queue[0]
            queue.pop(0)
            if (end_time >= temp[0]) :
                result+=1
                end_time-=1
        break
    else :
        while (len(queue) > 0):
            if(tasks[i][1] < end_time) :
                temp = queue[0]
                queue.pop(0)
                if (end_time >= temp[0]) :
                    result+=1
                    end_time-=1 
                
            else :
                break
        queue.append(tasks[i])
        queue = sorted(queue, key=lambda x:x[0])
        end_time = tasks[i][1]
    
    i+=1
 
print(result)

 

中文分词模拟器

华为OD机试真题C卷-篇2_第6张图片
华为OD机试真题C卷-篇2_第7张图片
华为OD机试真题C卷-篇2_第8张图片


import re
import math
import sys
from queue import Queue
 
target_words = input().split(",")
target_len = []
for x in target_words:
    target_len.append(len(x))
 
words = input().split(",")
words_len = []
for x in words:
    words_len.append(len(x))
 
result = ""
k=0
flag = False
while(True):
    if(k>=len(target_words)):
        break
    else :
        dp = [0 for i in range(target_len[k] + 1)] 
        dp[target_len[k]] = 1 
        i = target_len[k] 
        while(i>=0):
            for j in range(len(words)):
                if(i + len(words[j]) <= target_len[k]) :
                    split_str=target_words[k][i: i + len(words[j])]
                    if (dp[i + len(words[j])]==1 and split_str==words[j]) : 
                        dp[i] = 1 
                        break
            i-=1
            
        if (dp[0]!=0) : 
            temp_res = ""
            i = 0
            while (True) :
                if(i >= target_len[k]):
                    break
                else :
                    pos = -1 
                    for j in range(len(words)):
                        if (i + words_len[j] <= target_len[k]):
                            split_str=target_words[k][i: i + len(words[j])]
                            if(split_str == words[j]
                                and dp[i + words_len[j]]==1 and words_len[j] > pos) :
                                pos = words_len[j]
 
                    temp_res += target_words[k][i: i + pos] + ","
                    i += pos
            result += temp_res
        else :
            outut_str=""
            for i in range(len(target_len[k])):
                outut_str += char_arr[i]
                if(i!=len(char_arr)-1):
                    outut_str +=","
                
            flag = True
    k+=1
    
if(not flag):
    print(result[:-1])

 

手机App防沉迷系统

华为OD机试真题C卷-篇2_第9张图片
华为OD机试真题C卷-篇2_第10张图片

 
 
apps = []
def transfer(input_str):
    nums = [int(x) for x in input_str.split(":")]
    total = 60*nums[0] + nums[1]
    return str(total)
 
 
def solve(infos) :
    global apps
    new_apps = []
    for app in apps:
        if (not (app[2]<=infos[3] and app[3]>=infos[2] and app[1] < infos[1])) :
            new_apps.append(app);
    apps = new_apps;
    
  
    flag = False
    for i in range(len(apps)):
        if (apps[i][2]<=infos[3] and apps[i][3]>=infos[2] and apps[i][1] >= infos[1]) :
          flag = True
    if (not flag) :
        apps.append(infos)
 
n = int(input())
for i in range(n):
    infos = input().split(" ")
    infos[2] = transfer(infos[2])
    infos[3] = transfer(infos[3])
 
    solve(infos)
 
target = transfer(input())
output_str = "NA"
for i in range(len(apps)):
    if (target>=apps[i][2] and target<=apps[i][3]) :
        output_str = apps[i][0]
        break
print(output_str)

 

根据IP查找城市

华为OD机试真题C卷-篇2_第11张图片
华为OD机试真题C卷-篇2_第12张图片

 
def transfer(ip_str) :
    ips = [int(x) for x in ip_str.split(".")]
    result = 0
    for i in range(4):
        result = result * 256  
        result |= ips[i]
    return result
    
 
city_str = input().split(";") 
target_ip = input().split(",") 
ip_ranges = {}
for i in range(len(city_str)):
    ranges = city_str[i].split("=")[1].split(",") 
    if city_str[i].split("=")[0] in ip_ranges:
        ip_ranges[city_str[i].split("=")[0]].append([transfer(ranges[0]), transfer(ranges[1])])
    else:
        ip_ranges[city_str[i].split("=")[0]] = []
        ip_ranges[city_str[i].split("=")[0]].append([transfer(ranges[0]), transfer(ranges[1])])
 
 
output_str = ""
i=0
while(True):
    if(i>=len(target_ip)):
        break
    else :
        target_num = transfer(target_ip[i]) 
        target_city = "" 
        size = float('inf')
 
        for j in range(len(city_str)):
            ranges = ip_ranges[city_str[j].split("=")[0]]
            for k in range(len(ranges)):
                start = ranges[k][0]
                end = ranges[k][1]
                if (target_num >= start and target_num <= end) :
                    if (end - start < size) :
                        target_city = city_str[j].split("=")[0]
                        size = end - start
        output_str+=target_city+","
    
    i+=1
 
if(len(output_str) > 0):
    output_str= output_str[:-1]
print(output_str)

 

文件缓存系统

华为OD机试真题C卷-篇2_第13张图片
华为OD机试真题C卷-篇2_第14张图片

 
files= {}
total_value = 0
times = 1
m = int(input())
n = int(input())
for i in range(n):
    operations = input().split(" ")
    if (operations[0]=="get") :
        if(operations[1] in files) :
            file_info = files[operations[1]]
            file_info[1]+=1
            file_info[2] = times
            times += 1
            files[operations[1]] = file_info
        else :
            continue
    else :
        if( operations[1] not in files) :
            file_size = int(operations[2])
            if (total_value + file_size > m) :
                my_list = []
                for x in files:
                    my_list.append([x, files[x]])
                my_list = sorted(my_list, key=lambda x:(x[1][1], x[1][2]))
        
                for j in range(len(my_list)):
                    single_file = my_list[j]
                    if (total_value + single_file[1][0] >= m) :
                        files.pop(single_file[0])
                        total_value = total_value - single_file[1][0]
                    else :
                        break
 
            
            if (total_value + file_size <= m) :
                total_value += file_size
                files[operations[1]] =  [file_size, 0, times]
                times += 1
            
if (len(files)==0) :
    print("NONE")
else :
    
    my_list = []
    for x in files:
        my_list.append(x)
    
    my_list.sort()
    output_str= ""
    for i in range(len(my_list)):
        output_str += my_list[i]
        if(i!=len(my_list)-1):
            output_str += ","
        
    print(output_str)  
            

 

寻找最优的路测线路

华为OD机试真题C卷-篇2_第15张图片
华为OD机试真题C卷-篇2_第16张图片
在这里插入图片描述

import functools
import sys
import copy
import re
import math
 
def dfs(R, C, x, y, threshold, matrix, visited) :
    if (x == R - 1 and y == C - 1) :
        return True
    elif (threshold > matrix[x][y]) :
        return False
    else :
        visited[x][y] = 1
        dirtection = [-1,0,1,0,-1]
        for i in range(4):
            new_x = x + dirtection[i]
            new_y = y + dirtection[i+1]
            if (new_x >= 0 and new_x < R and new_y >= 0 and
                new_y < C and visited[new_x][new_y]==0 and matrix[new_x][new_y] >= threshold) :
                if (dfs(R,C,new_x,new_y,threshold, matrix,visited)) :
                    return True
        return False
 
R = int(input())
C = int(input())
matrix = []
visited = []
for i in range(R):
    matrix.append([int(x) for x in input().split(" ")])
    visited.append([0 for x in range(C)])
    
 
 
left = 0
right = 65535
while(True):
    if(left >= right):
        break
    else :
        mid = (left + right) >> 1
        for i in range(R):
            for j in range(C):
                visited[i][j] = 0
        if (dfs(R,C,0, 0, mid,matrix,visited)):
            left = mid
        else :
            right = mid - 1
print(left)

 

Wonderland游乐园

华为OD机试真题C卷-篇2_第17张图片

import functools
import sys
import copy
import re
import math
 
costs =  [int(x) for x in input().split(" ")]
days =  [int(x) for x in input().split(" ")]
 
dp = [float('inf') for x in range(400)]
dp[0] = 0
j = 0
for i in range(1, 366):
    if (j<len(days) and i == days[j]) :
        dp[i] = min(dp[i], dp[max(0, i - 1)] + costs[0])
        dp[i] = min(dp[i], dp[max(0, i - 3)] + costs[1])
        dp[i] = min(dp[i], dp[max(0, i - 7)] + costs[2])
        dp[i] = min(dp[i], dp[max(0, i - 30)] + costs[3])
        j+=1
    else:
        dp[i] = dp[i - 1]
print(dp[365])

 

项目排期/最少交付时间

华为OD机试真题C卷-篇2_第18张图片
二分法


def backtrace(pos, threshold) :
    if (len(nums) <= pos) :
        return True
    i=0
    while(True):
        if(i>=n):
            break
        else :
            total_v = nums[pos] + jobs[i]
            if (total_v > threshold) :
                if (jobs[i] == 0 or total_v == threshold) :
                    break
            else :
                jobs[i] += nums[pos]
                if (backtrace(pos + 1, threshold)) :
                    return True
                jobs[i] -= nums[pos]
        i+=1
    
    return False
 
 
nums = [int(x) for x in input().split(" ")]
total =0
for i in range(len(nums)):
    total += nums[i]
    
n = int(input())
jobs = [0 for i in range(len(nums))]
nums.sort()
 
low = nums[0]
high = total / n + 1
while (True):
    if(low >= high):
        break
    else :
        mid = int((low + high) / 2)
        if (backtrace(0 ,mid)) :
            high = mid
        else :
            low = mid + 1
print(low)

 

灰度图存储

华为OD机试真题C卷-篇2_第19张图片
华为OD机试真题C卷-篇2_第20张图片
华为OD机试真题C卷-篇2_第21张图片


 
nums1 = [int(x) for x in input().split(" ")]
nums2 = [int(x) for x in input().split(" ")]
target_position = nums2[0]*nums1[1] + nums2[1] + 1
total_sum = 0
i=3
while(True):
    if(i>=len(nums1)):
        break
    else :
        if (total_sum + nums1[i] < target_position) :
            total_sum += nums1[i]
        else :
            print(nums1[i - 1])
            break
    i+=2

 

精准核酸检测

华为OD机试真题C卷-篇2_第22张图片
华为OD机试真题C卷-篇2_第23张图片

 
n = int(input())
target = [int(x) for x in input().split(",")]
visited = [0 for x in range(n)]
matrix = []
for i in range(n):
    matrix.append([int(x) for x in input().split(",")])
 
def dfs(index) :
    visited[index] = 1
    i=0
    while(True):
        if(i>=n):
            break
        else :
            if (matrix[index][i] == 1 and visited[i]==0) :
                dfs(i) 
        i+=1
            
        
 
for i in range(len(target)):
    dfs(target[i])
 
result = 0
i=0
while(True):
    if(i>=n):
        break
    else :
        if (visited[i]==1) :
            flag = False
            for j in range(len(target)):
                if(target[j] == i):
                    flag = True
                    break
            
            if(not flag) :
                result += 1
    i+=1
print(result)

 

运输时间

华为OD机试真题C卷-篇2_第24张图片
华为OD机试真题C卷-篇2_第25张图片


 
params = [int(x) for x in input().split(" ")]
M = params[0]  
N = params[1]  
 
cars = []
for i in range(M):
    cars.append(int(input()))
result = 0
i=0
while(True):
    if(i>=M):
        print(result)
        break
    else:
        if (i == 0):
            result = N / cars[i]
        elif(result <= N / cars[i] + 1):
            result = N / cars[i]
        else:
            result = result - 1
    i+=1

 

你可能感兴趣的:(算法与数据结构(python),华为od,算法刷题,python)