华为OD机考十题解答-- Python3

⚠️ 首先说明,多去牛客网练练ACM模式

1、求解连续序列

已知连续正整数数列{K}=K1,K2,K3…Ki的各个数相加之和为S,i=N (0<S<100000, 0<N<100000), 求此数列K。

输入描述:

输入包含两个参数,1)连续正整数数列和S,2)数列里数的个数N。

输出描述:

如果有解输出数列K,如果无解输出-1

示例1

输入

525 6

输出

85 86 87 88 89 90

示例2

输入

3 5

输出

-1

class SeqCa:
    def solution(self, num, k):
        Flag = 0
        start = int((num / k) - k)
        end = (num // k) + k
        for i in range(start, end):
            if sum(range(i, i + k)) == num:
                print(" ".join(list(map(str, range(i, i + k)))))
                Flag = 1
                break
        if Flag == 0:
            print(-1)

if __name__ == "__mian__":
	SeqCa().solution(525, 6)
2、查找众数及中位数

众数是指一组数据中出现次数量多的那个数,众数可以是多个

中位数是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数为偶数,那就把中间的两个数之和除以2,所得的结果就是中位数

查找整型数组中元素的众数并组成一个新的数组,求新数组的中位数

输入描述:

输入一个一维整型数组,数组大小取值范围 0<N<1000,数组中每个元素取值范围 0<E<1000

输出描述:

输出众数组成的新数组的中位数

示例1:

输入

10 11 21 19 21 17 21 16 21 18 15

输出

21

示例2:

输入

2 1 5 4 3 3 9 2 7 4 6 2 15 4 2 4

输出

3

示例3:

输入

5 1 5 3 5 2 5 5 7 6 7 3 7 11 7 55 7 9 98 9 17 9 15 9 9 1 39

输出

7

class CheckList:

    def find(self, array):
        '''
        :param array: 目标数组
        :return: 新数组的中位数
        '''
        dict_tmp = {}
        list_tmp = []
        for i in set(array):
            dict_tmp[i] = array.count(i)
        max_target = max(value for value in dict_tmp.values())
        for key in dict_tmp.keys():
            if dict_tmp[key] == max_target:
                list_tmp.append(key)
        if len(list_tmp) % 2 != 0:
            print(list_tmp[(len(list_tmp) // 2)])
        else:
        """
        这里有个坑,要注意,如果众数有多个且众数个数是偶数个时,取中间的两个众数之和后除以2,如果恰好整数后是浮点数,那这个数输出是没有问题的,
        但是,如果这两个数和除以2正好是个整数,那这个输出按之前的输出就有问题,会打印成比如2.0,3.0这种,所以对于众数的的计算后的值还要进行判断,
        只使用#print((list_tmp[len(list_tmp) // 2] + list_tmp[len(list_tmp) // 2 - 1]) /2)这个输出是不可以的。
        """
        	    if str((new_list[(len(new_list) // 2)] + new_list[(len(new_list) // 2) - 1]) / 2).split(".")[-1]=="0":
        			print(int((new_list[(len(new_list) // 2)] + new_list[(len(new_list) // 2) - 1]) / 2))
   				else:
       			    print((new_list[(len(new_list) // 2)] + new_list[(len(new_list) // 2) - 1]) / 2)
           


CheckList().find([10, 11, 21, 19, 21, 17, 21, 16, 21, 18, 15])

3、寻找相同子串

给你两个字符串 t 和 p ,要求从 t 中找到一个和 p 相同的连续子串,并输出该字串第一个字符的下标。

输入描述:

输入文件包括两行,分别表示字符串 t 和 p ,保证 t 的长度不小于 p ,且 t 的长度不超过1000000,p 的长度不超过10000。

输出描述:

如果能从 t 中找到一个和 p 相等的连续子串,则输出该子串第一个字符在t中的下标(下标从左到右依次为1,2,3,…);如果不能则输出”No”;如果含有多个这样的子串,则输出第一个字符下标最小的。

示例1

输入

AVERDXIVYERDIAN

RDXI

输出

4

class CommSeek:
    def seek(self, t, p):
        """
        :param t:目标字符串
        :param p:子字符串
        :return:匹配到子字符串的第一个元素索引(非实际索引)
        """
        if len(t) >= len(p) and p in t:
            print(t.find(p)+1)
        else:
            print('No')


cn = CommSeek()
cn.seek('AVERDXIVYERDIDXAN', 'DX')

4、字符串统计

给定两个字符集合,一个为全量字符集,一个为已占用字符集。已占用的字符集中的字符不能再使用,要求输出剩余可用字符集。

输入描述:

1、输入为一个字符串,一定包含@符号。@前的为全量字符集,@后的字为已占用字符集。

2、已占用字符集中的字符一定是全量字符集中的字符。字符集中的字符跟字符之间使用英文逗号分隔。

3、每个字符都表示为字符加数字的形式,用英文冒号分隔,比如a:1,表示1个a字符。

4、字符只考虑英文字母,区分大小写,数字只考虑正整形,数量不超过100。

5、如果一个字符都没被占用,@标识仍然存在,例如a:3,b:5,c:2@

输出描述:

输出可用字符集,不同的输出字符集之间回车换行。

注意,输出的字符顺序要跟输入一致。不能输出b:3,a:2,c:2

如果某个字符已全被占用,不需要再输出。

示例1

输入

a:3,b:5,c:2@a:1,b:2

输出

a:2,b:3,c:2

说明

全量字符集为3个a,5个b,2个c。

已占用字符集为1个a,2个b。

由于已占用字符不能再使用,因此,剩余可用字符为2个a,3个b,2个c。

因此输出a:2,b:3,c:2

def reststrs(inputstring):
    allzips = inputstring.split('@')[0].split(',')
    usezips = inputstring.split('@')[1].split(',')
    allalpha, usedalpha = [], []
    allnum, usenum = [], []
    rest = ""
    for all in allzips:
        allalpha.append(all.split(":")[0])
        allnum.append(int(all.split(':')[1]))
    try:
        for used in usezips:
            usedalpha.append(used.split(':')[0])
            usenum.append(int(used.split(":")[1]))
    except:
        pass
    for i in range(len(allalpha)):
        restalpha = allalpha[i]
        if allalpha[i] not in usedalpha:
            restnum = allnum[i]
        else:
            restnum = allnum[i] - usenum[usedalpha.index(allalpha[i])]
        if restnum > 0 :
            if rest == "":
                rest = restalpha+":"+str(restnum)+','
            else:
                rest = rest+restalpha+":"+str(restnum)+","
    return rest
if __name__ == '__main__':
    strs = "A:3,a:4,b:5,c:2@a:1,b:4"
    print(reststrs(strs)[:-1])
5、磁盘容量排序

磁盘的容量单位常用的有M,G,T这三个等级,它们之间的换算关系为1T = 1024G,1G = 1024M,现在给定n块磁盘的容量,请对它们按从小到大的顺序进行稳定排序,例如给定5块盘的容量,1T,20M,3G,10G6T,3M12G9M排序后的结果为20M,3G,3M12G9M,1T,10G6T。注意单位可以重复出现,上述3M12G9M表示的容量即为3M+12G+9M,和12M12G相等。

输入描述:

输入第一行包含一个整数n(2 <= n <= 100),表示磁盘的个数,接下的n行,每行一个字符串(长度大于2,小于30),表示磁盘的容量,由一个或多个格式为mv的子串组成,其中m表示容量大小,v表示容量单位,例如20M,1T,30G,10G6T,3M12G9M。

磁盘容量m的范围为1到1024的正整数,容量单位v的范围只包含题目中提到的M,G,T三种,换算关系如题目描述。

输出描述:

输出n行,表示n块磁盘容量排序后的结果。

示例1:

输入

3

1G

2G

1024M

输出

1G

1024M

2G

说明

1G和1024M容量相等,稳定排序要求保留它们原来的相对位置,故1G在1024M之前

示例2:

输入

3

2G4M

3M2G

1T

输出

3M2G

2G4M

1T

说明

1T的容量大于2G4M,2G4M的容量大于3M2G


# -*- coding:utf-8 -*-
# @Time     :2022/6/13 15:48
# @Author   :wangwei
# @Software :PyCharm
"""
答案原文链接:https://blog.csdn.net/meiribaofu/article/details/116710453
"""

import re
import sys
num = int(input())
inputArr = []
for i in range(num):
    inputArr.append(sys.stdin.readline().strip())
res = []
for x in inputArr:
    singleSize = re.findall('(\d+\w)',x)
    size = 0
    for item in singleSize:
        if item[-1] == "M":
            size += int(item[:-1])
        elif item[-1]=="G":
            size += int(item[:-1])*1024
        elif item[-1] == 'T':
            size += int(item[:-1])*1024*1024
    res.append(((x,size)))
def sorted_by_size(x):
    return x[1]
for i in  sorted(res,key=sorted_by_size):
    print(i[0])
6、太阳能板最大面积

给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。如图:

现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为1个单位长度,计算如何选择两根支柱可以使太阳能板的面积最大。

输入描述:

10,9,8,7,6,5,4,3,2,1

注:支柱至少有2根,最多10000根,能支持的高度范围1~10^9的整数。柱子的高度是无序的,例子中递减只是巧合。

输出描述:

可以支持的最大太阳能板面积:(10米高支柱和5米高支柱之间)

25

示例1

输入

10,9,8,7,6,5,4,3,2,1

输出

25

备注:

10米高支柱和5米高支柱之间宽度为5,高度取小的支柱高也是5,面积为25。任取其他两根支柱所能获得的面积都小于25。所以最大的太阳能板面积为25。

# -*- coding:utf-8 -*-
# @Time     :2022/6/13 17:54
# @Author   :wangwei
# @Software :PyCharm
"""
答案为借鉴java答案转为python写法
原java代码答案地址https://blog.csdn.net/private_object/article/details/118162476
"""
def area():
    sc  = input()
    arr = sc.split(',')
    res = 0
    lenth = len(arr)
    for i in range(lenth):
        for j in range(i+1,lenth):
             a = int(arr[i])
             b = int(arr[j])
             c = abs(a-b)
             if a > b:
                 if res < b*c:
                     res = b*c
             else:
                if res < a*c:
                    res = a*c
    print(res)
area()
7、出租车计费

程序员小明打了一辆出租车去上班。出于职业敏感,他注意到这辆出租车的计费表有点问题,总是偏大。

出租车司机解释说他不喜欢数字4,所以改装了计费表,任何数字位置遇到数字4就直接跳过,其余功能都正常。

比如:

  1. 23再多一块钱就变为25;
    
  2. 39再多一块钱变为50;
    
  3. 399再多一块钱变为500;
    

小明识破了司机的伎俩,准备利用自己的学识打败司机的阴谋。

给出计费表的表面读数,返回实际产生的费用。

输入描述:

只有一行,数字N,表示里程表的读数。

(1<=N<=888888888)。

输出描述:

一个数字,表示实际产生的费用。以回车结束。

示例1:

输入

5

输出

4

说明

5表示计费表的表面读数。

4表示实际产生的费用其实只有4块钱。

示例2:

输入

17

输出

15

说明

17表示计费表的表面读数。

15表示实际产生的费用其实只有15块钱。

示例3:

输入

100

输出

81

说明

100表示计费表的表面读数。

81表示实际产生的费用其实只有81块钱。

"""
答案为借鉴,是将c++写的代码转为python代码,原c++答案链接:https://www.jianshu.com/p/fd19286a8339
这里是使用了9进制进行运算,还有个很简单的方法,但是那个方法在输入的数字很大时性能会非常差,会导致超时,这里就不写了。
"""
def actruly_cost():
    num = int(input())
    res = 0
    i = 0
    while num:
        d = num % 10
        num //= 10 #这里是结束循环的条件,当num为0时,会在此次循环后结束循环
        if d > 4:
            d -= 1
        res += pow(9,i)*d
        i+=1
    print(res)

actruly_cost()
8、整数对最小和

给定两个整数数组array1、array2,数组元素按升序排列。假设从array1、array2中分别取出一个元素可构成一对元素,现在需要取出k对元素,并对取出的所有元素求和,计算和的最小值

注意:两对元素如果对应于array1、array2中的两个下标均相同,则视为同一对元素。

输入描述:

输入两行数组array1、array2,每行首个数字为数组大小size(0 < size <= 100);

0 < array1[i] <= 1000

0 < array2[i] <= 1000

接下来一行为正整数k

0 < k <= array1.size() * array2.size()

输出描述:

满足要求的最小和

示例1

输入

3 1 1 2

3 1 2 3

2

输出

4

说明

用例中,需要取2对元素

取第一个数组第0个元素与第二个数组第0个元素组成1对元素[1,1];

取第一个数组第1个元素与第二个数组第0个元素组成1对元素[1,1];

求和为1+1+1+1=4,为满足要求的最小和

"""
该答案为借鉴,是将原java解法改为python解法
原java答案链接:https://blog.csdn.net/hellolianhua/article/details/118859536
"""

def min_sum():
    stringA = input()
    stringB = input()
    k = int(input())
    list_a = stringA.strip().split(' ')
    list_b = stringB.strip().split(' ')
    list_c = []
    for i in list_a:
        for j in list_b:
            list_c.append(int(i)+int(j))
    list_c.sort()
    s=0
    for i in range(k):
        s+=list_c[i]
    print(s)
    
min_sum()
9、判断字符串子序列

给定字符串 target和 source, 判断 target 是否为 source 的子序列。

你可以认为 target 和 source 中仅包含英文小写字母。字符串 source可能会很长(长度 ~= 500,000),而 target 是个短字符串(长度 <=100)。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"abc"是"aebycd"的一个子序列,而"ayb"不是)。

请找出最后一个子序列的起始位置。

输入描述:

第一行为target,短字符串(长度 <=100)

第二行为source,长字符串(长度 ~= 500,000)

输出描述:

最后一个子序列的起始位置, 即最后一个子序列首字母的下标

示例1

输入

abc

abcaybec

输出

3

说明

这里有两个abc的子序列满足,取下标较大的,故返回3

备注:

若在source中找不到target,则输出-1

"""
该答案为借鉴,将java解法转换为python写法
"""
def find_seq():
    target = input()
    source = input()
    i = len(target) - 1
    j = len(source) - 1
    while i >= 0 and j >= 0:
        if (target[i]==source[j]):
            if i == 0 :
                print(j)
                return #return的作用是return之后的代码不会执行
            i-=1
        j-=1
    print(-1)
    
find_seq()
10、按身高和体重排队某学校举行运动会,学生们按编号(1、2、3…n)进行标识,现需要按照身高由低到高排列,对身高相同的人,按体重由轻到重排列;对于身高体重都相同的人,维持原有的编号顺序关系。请输出排列后的学生编号。

输入描述:

两个序列,每个序列由n个正整数组成(0 < n <= 100)。第一个序列中的数值代表身高,第二个序列中的数值代表体重。

输出描述:

排列结果,每个数值都是原始序列中的学生编号,编号从1开始

示例1:

输入

4

100 100 120 130

40 30 60 50

输出

2 1 3 4

说明

输出的第一个数字2表示此人原始编号为2,即身高为100,体重为30的这个人。由于他和编号为1的人身高一样,但体重更轻,因此要排在1前面。

示例2:

输入

3

90 110 90

45 60 45

输出

1 3 2

说明

1和3的身高体重都相同,需要按照原有位置关系让1排在3前面,而不是3 1 2

n = int(input())
height = input().strip().split() 
weight = input().strip().split()

arr1 = []
for i in range(n):
    arr1.append(((int(height[i]), int(weight[i])), i + 1)) #arr1是列表,其中元素是元组,元组中又包含元组
arr2 = sorted(arr1, key=lambda x: x[0])#使用匿名函数将arr1按照arr1元素中的第一个元素为key排序
for i in arr2:
    print(i[1], end=' ') #这里就是输出排序后的列表元素中的元素的第二个元素
  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值