牛客华为机试

1. 计算字符个数

import sys
def main():
    # hashmap辅助
    lines = sys.stdin.readlines()
    s = lines[0].strip()
    t = lines[1].strip()

    if len(s) == 0:
        return 0

    hashmap = dict()
    for c in s:
        hashmap[c.upper()] = hashmap.get(c.upper(), 0) + 1

    print(hashmap.get(t.upper(), 0))

if __name__ == "__main__":
    main()


2. 字符串最后一个单词的长度

import sys
def main():
    s = sys.stdin.readlines()[0].strip()
    if len(s) == 0:
        return 0
    n = len(s)
    right = n - 1
    lenght = 0
    # 如果最右边的第一个就是" "的话, 就跳过这些空格
    while right >= 0 and s[right] == " ":
        right -= 1
    while right >= 0 and s[right] != " ":
        lenght += 1
        right -= 1
    print(lenght)

if __name__ == "__main__":
    main()

3. 明明的随机数

和Leetcode的移动零很相似

import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    
    # 第一组数的起点(该组数有几个)
    start = 0
    for i, num in enumerate(lines):
        if start == i:
            nums = []
            n = int(num.strip())
            # 下一个数组的起点(第一个数记录了该组数有几个)
            start = (start + n) + 1
            # print("start", start)
        else:
            nums.append(int(num.strip()))
            if i == start - 1:  # 当前数组的end
                # 类似移动0的方法
                nums.sort()
                l = 0
                for j, num in enumerate(nums):
                    if nums[l] != nums[j]:
                        l += 1
                        nums[l] = nums[j]
                for num in nums[:l + 1]:
                    print(num)


if __name__ == "__main__":
    main()

 

4. 字符串分隔

import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    for line in lines:
        line = list(line.strip())
        while len(line) > 8:
            print(''.join(line[0: 8]))
            line = line[8:]
        new_line = ['0'] * 8
        new_line[0: len(line)] = line
        print(''.join(new_line))
if __name__ == "__main__":
    main()

 

5. 进制转换

自己写算法的话是这样,还可以直接调用python自带的API直接将16进制字符串转为10进制

while True:
    try:
        # 先去除0x
        x_num = input()[2:]
        d_num = 0
        length = len(x_num)
        # 从高位遍历到低位
        for i in range(length):
            if x_num[i] == 'A':
                d_num += 10 * (16 ** (length - 1 - i))
            elif x_num[i] == 'B':
                d_num += 11 * (16 ** (length - 1 - i))
            elif x_num[i] == 'C':
                d_num += 12 * (16 ** (length - 1 - i))
            elif x_num[i] == 'D':
                d_num += 13 * (16 ** (length - 1 - i))
            elif x_num[i] == 'E':
                d_num += 14 * (16 ** (length - 1 - i))
            elif x_num[i] == 'F':
                d_num += 15 * (16 ** (length - 1 - i))
            else:
                d_num += int(x_num[i]) * (16 ** (length - 1 - i))
        print(d_num)
    except:
        break
while True:
    try:
        strNum = input().strip()
        print(int(strNum, base=16))
    except:
        break

6.  质数因子

import sys
import math
# 判断质数
def isPrime(n):
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

def countPrimes(num):
    while (num > 1):
        # 遍历[2, num], 判断出为质数的约数
        for n in range(2, num + 1):  
            if num % n == 0 and isPrime(n):
                print(n, end=" ")
                # 更新num
                num = num // n
                break
def main():
    num = int(sys.stdin.readline().strip())
    countPrimes(num)


if __name__ == "__main__":
    main()

7. 取近似值

import sys
def main():
    num = sys.stdin.readline().strip()
    num = num.split('.')
    point = num[-1]
    if int(point) >= 5:
        print(int(num[0]) + 1)
    else:
        print(int(num[0]))

if __name__ == "__main__":
    main()

8. 合并表记录

import sys
def main():
    sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = int(lines[0].strip())
    hashmap = dict()
    for l in lines[1: n+1]:
        l = l.strip().split()
        l = list(map(int, l))
        key = l[0]
        value = l[1]
        hashmap[key] = hashmap.get(key, 0) + value

    for key in hashmap.keys():
        print(key, hashmap[key])

if __name__ == "__main__":
    main()

9. 提取不重复的整数

import sys
def reverse(nums):
    i = 0
    j = len(nums) - 1
    while(i < j):
        tmp = nums[i]
        nums[i] = nums[j]
        nums[j] = tmp
        i += 1
        j -= 1
    return nums

def main():
    lines = sys.stdin.readline()
    numbers = list(lines.strip())
    n = len(numbers)
    i = n - 1
    # 哈希辅助+双指针
    hashmap = dict()
    for j in range(n-1, -1, -1):
        if numbers[j] not in hashmap.keys():
            hashmap[numbers[j]] = 1
            numbers[i] = numbers[j]
            i -= 1

    print(''.join(reverse(numbers[i + 1:])))


if __name__ == "__main__":
    main()

10. 字符个数统计

import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    line = sys.stdin.readline().strip()
    hashmap = dict()
    n = len(line)
    for i in range(n):
        if line[i] not in hashmap:
            hashmap[line[i]] = 1
    print(len(hashmap))

if __name__ == "__main__":
    main()

11. 数字颠倒

import sys
def main():
    number = sys.stdin.readline().strip()
    reverse = []
    n = len(number)
    for i in range(n-1, -1, -1):
        reverse.append(number[i])
    print(''.join(reverse))

if __name__ == "__main__":
    main()

12. 字符串反转

import sys
def reverse(s):
    l = 0
    r = len(s) - 1
    reverse = list(s)
    while l < r:
        reverse[l], reverse[r] = reverse[r], reverse[l]
        l += 1
        r -= 1
    return reverse

def main():
    s = sys.stdin.readline().strip()
    rev = reverse(s)
    print(''.join(rev))

if __name__ == "__main__":
    main()

13. 句子逆序

对于python的语法来说,13题和12题基本上没有什么差别,无非是将list中的元素从char换到string罢了

import sys
def reverse(s):
    l = 0
    r = len(s) - 1
    reverse = list(s)
    while l < r:
        reverse[l], reverse[r] = reverse[r], reverse[l]
        l += 1
        r -= 1
    return reverse

def main():
    line = sys.stdin.readline().strip()
    line = line.split()
    n = len(line)
    rev = reverse(line)
    for i in range(n):
        if i < n - 1:
            print(rev[i], end=' ')
        else:
            print(rev[i])


if __name__ == "__main__":
    main()

14. 字串的连接最长路径查找

import sys
def main():
    lines = sys.stdin.readlines()
    n = int(lines[0].strip())
    strings = list()
    for i in range(n):
        strings.append(lines[i + 1].strip())
    strings.sort()
    for i in range(n):
        print(strings[i])

if __name__ == "__main__":
    main()

15. 求int型正整数在内存中存储时1的个数

import sys
def main():
    while True:
        try:
            count = 0
            n = int(input())
            while n >= 1:
                rest = n % 2
                n = n // 2
                count += rest
            print(count)
        except:
            break
if __name__ == "__main__":
    main()

16. 购物单

# 0-1背包问题的变体
n, m = map(int,input().split())
primary, annex = {}, {}
for i in range(1,m+1):
    x, y, z = map(int, input().split())
    if z==0:#主件
        primary[i] = [x, y]
    else:#附件
        if z in annex:#第二个附件
            annex[z].append([x, y])
        else:#第一个附件
            annex[z] = [[x,y]]
m = len(primary)#主件个数转化为物品个数
dp = [[0]*(n+1) for _ in range(m+1)]
w, v= [[]], [[]]
for key in primary:
    w_temp, v_temp = [], []
    w_temp.append(primary[key][0])#1、主件
    v_temp.append(primary[key][0]*primary[key][1])
    if key in annex:#存在主件
        w_temp.append(w_temp[0]+annex[key][0][0])#2、主件+附件1
        v_temp.append(v_temp[0]+annex[key][0][0]*annex[key][0][1])
        if len(annex[key])>1:#存在两附件
            w_temp.append(w_temp[0]+annex[key][1][0])#3、主件+附件2
            v_temp.append(v_temp[0]+annex[key][1][0]*annex[key][1][1])
            
            w_temp.append(w_temp[0]+annex[key][0][0]+annex[key][1][0])#3、主件+附件1+附件2
            v_temp.append(v_temp[0]+annex[key][0][0]*annex[key][0][1]+annex[key][1][0]*annex[key][1][1])
    w.append(w_temp)
    v.append(v_temp)
    
# 主件 + 附件才是一个物品 (但是同一个主件可以有很多种附带,取其中大的就行)
for i in range(1, m+1):
    for j in range(10,n+1,10):#物品的价格是10的整数倍
        # 第i个主件装进背包
        max_i = dp[i-1][j]
        for k in range(len(w[i])):
            if j-w[i][k]>=0:
                max_i = max(max_i, dp[i-1][j-w[i][k]]+v[i][k])
        dp[i][j] = max_i
print(dp[m][n])

17. 坐标移动

import sys
validNumber = list(map(str, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
validChar = ['A', 'W', 'D', 'S']

def isVaild(direction, step):
    flag = True
    if direction not in validChar:
        flag = False
    for num in step:
        if num not in validNumber:
            flag = False
    return flag

def move(direction, step):
    if direction == 'A':
        return [-step, 0]
    elif direction == 'W':
        return [0, step]
    elif direction == 'D':
        return [step, 0]
    elif direction == 'S':
        return [0, -step]

def main():
    lines = sys.stdin.readlines()
    for line in lines:
        line = line.strip()
        opts = line.split(';')
        start = [0, 0]
        for opt in opts:
            if len(opt) < 2:
                continue
            direction = opt[0]
            step = opt[1:]
            if isVaild(direction, step):
                step = int(step)
                shift = move(direction, step)
                start[0] += shift[0]
                start[1] += shift[1]
        print(str(start[0])+','+str(start[1]))


if __name__ == "__main__":
    main()

18.识别有效的IP地址和掩码并进行分类统计

正则表达式穷举匹配的,嫌麻烦我没自己写代码,就当遇见过这类题

import re

error_pattern = re.compile(r'1+0+')
A_pattern = re.compile(r'((12[0-6]|1[0-1]\d|[1-9]\d|[1-9])\.)((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
B_pattern = re.compile(r'(12[8-9]|1[3-8]\d|19[0-1])\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
C_pattern = re.compile(r'(19[2-9]|2[0-1]\d|22[0-3])\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
D_pattern = re.compile(r'(22[4-9]|23\d)\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
E_pattern = re.compile(r'(24\d|25[0-5])\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)')
self_pattern = re.compile(r'((10\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d))|(172\.(1[6-9]|2\d|3[0-1])\.(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d))|(192\.168\.(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)))')
escape = re.compile(r'((0|127)\.((1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d))')
def judge_error(line):
    if line == '255.255.255.255' or line == '0.0.0.0':
        return 0
    judge = line.split('.')
    res = ''
    for j in judge:
        res += '{:0>8b}'.format(int(j))
    res = re.fullmatch(error_pattern, res)
    if res == None:
        return 0
    else:
        return 1

def judge(pattern, line):
    if re.fullmatch(pattern, line) != None:
        return 1
    else:
        return 0

stack = [0]*7
while True:
    try:
        line = input().split('~')
        if judge_error(line[1]):
            if judge(self_pattern, line[0]):
                stack[6] += 1
            if judge(A_pattern, line[0]):
                stack[0] += 1
            elif judge(B_pattern, line[0]):
                stack[1] += 1
            elif judge(C_pattern, line[0]):
                stack[2] += 1
            elif judge(D_pattern, line[0]):
                stack[3] += 1
            elif judge(E_pattern, line[0]):
                stack[4] += 1
            elif judge(escape, line[0]):
                continue
            else:
                stack[5] += 1
        else:
            stack[5] += 1
    except:
        print(' '.join([str(i) for i in stack]))
        break


19. 简单错误记录

一开始看难易度以为不好做,但是很简单,主要是仔细审题

# hashmap + 字符串
dic = dict()
name_lines = []
# 其实就是统计指定文件指定行号的数量
while True:
    try:
        lst = list(input().split())
        name = lst[0].split('\\')[-1][-16:]
        # 文件名 + ' ' + 行号
        name_line = name + ' ' + lst[1]
        dic[name_line] = dic.get(name_line, 0) + 1
        
        if name_line not in name_lines:
            name_lines.append(name_line)
            
    # 输入完毕之后便开始输出之前统计的数据
    # set()无法将二维list转为set,要用set的话要先将字符数组转为字符串
    except:
        for item in name_lines[-8:]:
            print(item + " " + str(dic[item]))
        break

20. 密码验证合格程序

要活用python中list的机制,交集,并集,差集,而且有的时候数组段的暴力搜索也不是一件坏事。

import sys
number = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
charBig = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}
charSmall = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}

def isVaild(line):
    line = list(line)
    n = len(line)
    if n <= 8:
        return False

    count = 0
    if len(list(set(line).intersection(number))) > 0:
        count += 1
    if len(list(set(line).intersection(charBig))) > 0:
        count += 1
    if count < 1:
        return False
    if len(list(set(line).intersection(charSmall))) > 0:
        count += 1
    if count < 2:
        return False
    if len(list(set(line).difference(set(list(number) + list(charSmall) + list(charBig))))) > 0:
        count += 1
    if count < 3:
        return False
    sub3s = []
    for i in range(n - 2):
        if line[i: i + 3] in sub3s:
            return False
        sub3s.append(line[i: i + 3])
    return True

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    for line in lines:
        line = line.strip()
        if isVaild(line):
            print('OK')
        else:
            print('NG')




if __name__ == "__main__":
    main()

21. 简单密码

import sys
# 字符串, 穷举匹配
number = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
hashmap = {
    '1': '1',
    'abc': '2',
    'def': '3',
    'ghi': '4',
    'jkl': '5',
    'mno': '6',
    'pqrs': '7',
    'tuv': '8',
    'wxyz': '9'
}
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    for line in lines:
        pw = ""
        line = line.strip()
        for c in line:
            if c.islower():
                for s in hashmap:
                    # 穷举匹配, python的这个in真的好用, 
                    # 字符串中能用,list也能用,
                    # 二维list中还能用
                    if c in s:
                        pw += hashmap[s]

            elif c.isupper():
                if c == 'Z':
                    nc = 'a'
                    pw += nc
                else:
                    # 字符和
                    nc = chr(ord(c.lower()) + 1)
                    pw += nc
            elif c in number:
                pw += c
        print(pw)
if __name__ == "__main__":
    main()

22.  删除字符串中出现次数最少的字符

import sys
def main():
        # sys.stdin = open('input.txt', 'r')
        lines = sys.stdin.readlines()
        for line in lines:
            hashmap = dict()
            line = line.strip()
            for c in line:
                hashmap[c] = hashmap.get(c, 0) + 1

            hashmapReverse = dict()

            for c in hashmap:
                if hashmap[c] not in hashmapReverse:
                    hashmapReverse[hashmap[c]] = []
                    hashmapReverse[hashmap[c]].append(c)
                else:
                    hashmapReverse[hashmap[c]].append(c)

            order = sorted(hashmapReverse)[0]
            dele = hashmapReverse[order]

            line = list(line)
            for d in dele:
                # python中的list的删除会保留list原来的顺序
                # 传入值进行删除
                line.remove(d)

            print(''.join(line))
            
if __name__ == "__main__":
    main()

23. 汽水瓶

import sys
# 数学题
# 由于有两空瓶的话可以借一瓶之后兑换到一瓶还回去
# 所以算下来是两个空瓶就能换一瓶水
def main():
    while True:
        try:
            num = input()
            num = int(num)
            if num == 0:
                pass
            else:
                print(num // 2)
        except:
            break
if __name__ == "__main__":
    main()

24. 合唱队

动态规划: 双向最长上升子序列

# 输入方式一,处理起来稍微麻烦点
import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    rows = len(lines)
    index = 0
    while index < rows:
        n = int(lines[index].strip())
        numbers = list(map(int, lines[index+1].strip().split()))

        dp1 = [1] * n
        dp2 = [1] * n

        for i in range(n):
            for j in range(0, i):
                if numbers[j] < numbers[i]:
                    dp1[i] = max(dp1[i], dp1[j] + 1)

        for i in range(n-1, -1, -1):
            for j in range(n-1, i, -1):
                if numbers[j] < numbers[i]:
                    dp2[i] = max(dp2[i], dp2[j] + 1)

        for i in range(n):
            dp1[i] += dp2[i]
            dp1[i] = dp1[i] - 1

        K = 1
        for i in range(n):
            K = max(dp1[i], K)

        print(n - K)
        index += 2


if __name__ == "__main__":
    main()


# 输入方式二
import sys
def main():
    while True:
        try:
            # 有的题目实例里面是一组输入,实际上会输入多组
            # 可以用下面的结构用于处理输入
            '''
            while True:
                try: 
                    ...
                except:
                    break
            '''
            n = int(input())
            numbers = list(map(int, input().strip().split()))

            dp1 = [1] * n
            dp2 = [1] * n

            for i in range(n):
                for j in range(0, i):
                    if numbers[j] < numbers[i]:
                        dp1[i] = max(dp1[i], dp1[j] + 1)

            for i in range(n-1, -1, -1):
                for j in range(n-1, i, -1):
                    if numbers[j] < numbers[i]:
                        dp2[i] = max(dp2[i], dp2[j] + 1)
            for i in range(n):
                dp1[i] += dp2[i]
                dp1[i] = dp1[i] - 1

            K = 1
            for i in range(n):
                K = max(dp1[i], K)

            print(n - K)

        except:
            break


if __name__ == "__main__":
    main()

25. 数据分类处理

这题仔细审题之后很简单,但是牛客的解答器绝对有问题

"""
题目描述这么多,最后干的事是:
1. 将规则数组排序(从小到大),并去重。
2. 遍历输入数组,检查输入数组的每个元素是是否包含规则数组中的数字i,如果包含则将输入数组元素位置和元素输出到最终结果中。
"""
import sys
def main():
        sys.stdin = open('input.txt', 'r')
        lines = sys.stdin.readlines()
        n = len(lines)
        for ln in range(0, n, 2):
            I = lines[ln].strip().split()[1:]
            R = lines[ln + 1].strip().split()[1:]
            ans = []

            R = list(map(str, sorted(set(list(map(int, R))))))

            for r in R:
                cur = dict()
                count = 0
                for index, i in enumerate(I):
                    if r in i:
                        count += 1
                        cur[index] = i

                if count > 0:
                    ans.append(r)
                    ans.append(str(count))
                    for j in cur:
                        ans.append(str(j))
                        ans.append(cur[j])
            num = len(ans)
            print(str(num)+' ' + ' '.join(ans))

if __name__ == "__main__":
    main()

26. 字符串排序

chars = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
import sys
import collections
def main():
        # sys.stdin = open('input.txt', 'r')
        lines = sys.stdin.readlines()
        for line in lines:
            line = line.strip().split()
            out = []
            for str in line:
                extrareverse = collections.deque([])
                extra = []

                str = list(str)
                for i, c in enumerate(str):
                    if c not in chars:
                        extrareverse.appendleft([i, c])
                        extra.append([i, c])

                for e in extrareverse:
                    # 这步很关键, 因为pop会改变str的结构, 使其缩小
                    str.pop(e[0])
                # 进行无视大小写的字典排序, 相同的字母保持原来的顺序(大写小写一样)
                str = [(x.lower(), x) for x in str]
                str.sort(key=lambda x: x[0])
                str = [x[1] for x in str]

                for e in extra:
                    str.insert(e[0], e[1])
                out.append(''.join(str))
            # print(' '.join(out), end=" ")
            print(' '.join(out))

if __name__ == "__main__":
    main()

27. 查找兄弟单词

import sys
def isBrother(s1, s2):
    if s1 == s2:
        return False
    
    # 用类似滑动窗口的办法判断其是否是兄弟
    need = dict()
    window = dict()
    
    for c in s1:
        need[c] = need.get(c, 0) + 1

    for c in s2:
        window[c] = window.get(c, 0) + 1

    if len(need) != len(window):
        return False

    for c in need:
        if need[c] != window.get(c, 0):
            return False

    return True

def main():
    while True:
        try:
            line = input().strip().split()
            n = int(line[0])
            brother = []

            for i in range(1, n + 1):
                if isBrother(line[-2].strip(), line[i]):
                    brother.append(line[i])
            # 将字符串序列先字典排序
            brother.sort()
            count = len(brother)
            print(count)
            # 注意处理临界情况
            if int(line[-1]) - 1 < count:
                print(brother[int(line[-1]) - 1])
        except:
            break

if __name__ == "__main__":
    main()

28. 素数伴侣

题解都是“匈牙利算法”,我表示没看过,我用的暴力穷举法,但是超时,所以只能背人家的题解了:

import sys
res = []
# 回溯求两个数的子集
def backtrack(track, start, n, number):
    if len(track) == 2:
        res.append(track[:])

    for i in range(start, n):
        track.append(number[i])
        backtrack(track, i + 1, n, number)
        track.pop()
# 判断两个数的和是否为素数
def totaliSPrime(re):
    total = re[0] + re[1]
    i = 2
    while i*i <= total:
        if total % i == 0:
            return False
        i += 1
    return True

# 穷举暴力求做大不重复集合
def getResults(results, ans, count, s, maxl):
    if count > maxl:
        maxl = count

    for an in ans:
        if an[0] not in s and an[1] not in s:
            s.append(an[0])
            s.append(an[1])
            results.append(an)
            maxl = getResults(results, ans, count + 1, s, maxl)
            s.pop()
            s.pop()
            results.pop()
    return maxl

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = int(lines[0].strip())
    numbers = list(map(int, lines[1].strip().split()))
    ans = []
    track = []
    backtrack(track, 0, n, numbers)

    for re in res:
        if totaliSPrime(re):
            ans.append(re)

    results = []
    s = []
    maxl = 0
    maxl = getResults(results, ans, 0, s, maxl)
    print(maxl)

if __name__ == "__main__":
    main()

29. 字符串加解密

import sys
a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
A = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
chrs = a + A
def encode(jia):
    jia = list(jia)
    for i, c in enumerate(jia):
        if c in chrs:
            if c == 'Z':
                jia[i] = 'a'
            elif c == 'z':
                jia[i] = 'A'
            else:
                if c.isupper():
                    jia[i] = chr(ord(c.lower()) + 1)
                else:
                    jia[i] = chr(ord(c.upper()) + 1)
        else:
            jia[i] = str((int(c) + 1) % 10)

    return ''.join(jia)

def decode(jie):
    jie = list(jie)
    for i, c in enumerate(jie):
        if c in chrs:
            if c == 'A':
                jie[i] = 'z'
            elif c == 'a':
                jie[i] = 'Z'
            else:
                if c.isupper():
                    jie[i] = chr(ord(c.lower()) - 1)
                else:
                    jie[i] = chr(ord(c.upper()) - 1)
        else:
            jie[i] = str((int(c) - 1) % 10)

    return ''.join(jie)

def main():
    while True:
        try:
            jia = input().strip()
            jie = input().strip()
            resultA = encode(jia)
            resultE = decode(jie)
            print(resultA)
            print(resultE)
        except:
            break
if __name__ == "__main__":
    main()

30. 字符串合并处理

主要利用了python自带的字典排序sorted()、字符串翻转reversed()和进制转换hex(), bin().

import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = len(lines)
    index = 0
    alphabet = '0123456789ABCDEFabcdef'
    while index < n:
        try:
            line = lines[index].strip().split()
            n1 = len(line[0])
            n2 = len(line[1])
            new_line = line[0] + line[1]

            n = n1 + n2
            oushu = []
            jishu = []

            for i in range(n):
                if i % 2 == 0:
                    oushu.append(new_line[i])
                else:
                    jishu.append(new_line[i])

            oushu = sorted(oushu)
            jishu = sorted(jishu)

            o = 0
            j = 0
            new_line = list(new_line)
            for i in range(n):
                if i % 2 == 0:
                    new_line[i] = oushu[o]
                    o += 1
                else:
                    new_line[i] = jishu[j]
                    j += 1

            ans = ""

            for c in new_line:
                if c in alphabet:
                    # 这里用了python自带的reversed()和进制转换(都要以10进制为桥梁)
                    # 但是有个bug就是, 如果进制转换的输入的字符是无效的话比如'G', 程序将不报错直接终止循环
                    # 然后输出大的ans还是空的, 所以要处理一下,不在alphabet中的字符将保留原型
                    ans += hex(int(''.join(list(reversed(bin(int('0x' + c, 16))[2:].zfill(4)))), base=2))[2:].upper()
                else:
                    ans += c
            print(ans)
            index += 1

        except:
            break


if __name__ == "__main__":
    main()

31. 【中级】单词倒排

import sys
# 使用python的split()和reversed(),主要需要注意的是将每个word中的非法字符转" "
def main():
    while True:
        try:
            line = input().strip().split()
            # 遍历字符串数组, 将每个字符串中的非法字符全部转为" "
            for j, w in enumerate(line):
                # 将原本是字符串的w转为list便于之后的修改
                w = list(w)
                for i, c in enumerate(w):
                    if (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z'):
                        continue
                    else:
                        w[i] = " "
                line[j] = ''.join(w)

            line = ' '.join(line).split()
            line = list(reversed(line))
            print(' '.join(line))
        except:
            break


if __name__ == "__main__":
    main()

32. 字符串运用-密码截取

import sys
# 题目原型: 最长回文子串
def longestPalindromeSubstring(line, nn, i, j):

    while i >= 0 and j < nn:
        if line[i] != line[j]:
            break
        i -= 1
        j += 1
    return j - i - 1

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = len(lines)
    index = 0
    while index < n:
        line = lines[index].strip()
        nn = len(line)
        l_max = 0
        for i in range(nn):
            l_ji = longestPalindromeSubstring(line, nn, i, i)
            l_ou = longestPalindromeSubstring(line, nn, i, i + 1)
            l_max = max(l_max, l_ji, l_ou)
        print(l_max)

        index += 1

if __name__ == "__main__":
    main()

33. 整数与IP地址间的转换

import sys
import collections
# 活用python中的进制转换接口
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = len(lines)
    index = 0
    while index < n:
        IP = lines[index].strip()
        IP = IP.split('.')
        catNums = ""
        for num in IP:
            # 保证二进制是8个一组
            catNums += bin(int(num))[2:].zfill(8)
        print(int(catNums, base=2))

        encodeIP = lines[index + 1].strip()
        encodeIP = bin(int(encodeIP))[2:]
        # 为了保证8个数字为一组, 在高位不足8个的组中补充"0"
        nn = len(encodeIP)
        fillnum = 32 - nn
        encodeIP = "0" * fillnum + encodeIP
        nnn = len(encodeIP)

        encodeIP_ans = []
        for i in range(0, nnn, 8):
            encodeIP_ans.append(str(int(encodeIP[i: i + 8], 2)))
        print('.'.join(encodeIP_ans))

        index += 2
if __name__ == "__main__":
    main()

34. 图片整理

import sys
import collections
# 活用python中的sorted()
def main():
    while True:
        try:
            line = input()
            line = line.strip()
            print(''.join(sorted(line)))
        except:
            break
            
if __name__ == "__main__":
    main()

35. 蛇形矩阵

import sys
lines = sys.stdin.readlines()
n = len(lines)
for index in range(0, n, 2):
    key = lines[index].strip()
    string = lines[index + 1].strip()

    chars = []
    
    # 去除重复的秘钥(都用大写来表示)
    for k in key:
        if k.upper() not in chars:
            chars.append(k.upper())
    # 将26个字母中的剩余字母接在chars的后面[65~91 是 A~B 的ASCII码]
    for i in range(65, 91):
        if chr(i) not in chars:
            chars.append(chr(i))
            
    # 根据s找到对应的秘钥,并保留s的大小写
    ans = ""
    for s in string:
        if s.isupper():
            ans += chars[ord(s) - 65]
        else:
            ans += chars[ord(s) - 97].lower()
    print(ans)
    index += 2


36. 字符串加密

import sys
lines = sys.stdin.readlines()
n = len(lines)
for index in range(0, n, 2):
    key = lines[index].strip()
    string = lines[index + 1].strip()

    chars = []
    
    # 去除重复的秘钥(都用大写来表示)
    for k in key:
        if k.upper() not in chars:
            chars.append(k.upper())
    # 将26个字母中的剩余字母接在chars的后面[65~91 是 A~B 的ASCII码]
    for i in range(65, 91):
        if chr(i) not in chars:
            chars.append(chr(i))
            
    # 根据s找到对应的秘钥,并保留s的大小写
    ans = ""
    for s in string:
        if s.isupper():
            ans += chars[ord(s) - 65]
        else:
            ans += chars[ord(s) - 97].lower()
    print(ans)
    index += 2


37. 统计每个月兔子的总数

终于又在华为的题目里面看见动态规划了

while True:
    try:
        num = int(input())
        dp = [0] * (num + 1)
        # 0表示第0个月,就是还么有开始
        # basecase
        dp[0] = 0
        dp[1] = 1
        # 两个月前的兔子可以生了(翻倍),一个月前刚刚出生的兔子还不能生育(保留)
        for i in range(2, num + 1):
            dp[i] = 2 * dp[i - 2] + (dp[i - 1] - dp[i - 2])
        print(dp[num])
    except:
        break

38. 求小球落地5次后所经历的路程和第5次反弹的高度

# 画个图, 或者把每次的高度写出来就能很快找到规律了
while True:
    try:
        l = float(input())
        ans = l
        for i in range(5):
            if i < 4:
                l = l / 2
                ans += 2 * l
            else:
                l = l / 2
        print(ans)
        print(l)

    except:
        break

40.判断两个IP是否属于同一子网

这题太麻烦我没做

def checklegality(s):
    flag = True
    if len(s) != 4:
        flag = False
        return flag
    for i in s:
        if not (i.isdecimal() and 0<=int(i)<=255):
            flag = False
    return flag

def tenToTwo(s):
    s2 = []
    for i in s:
        a2 = str(bin(int(i)))[2:]
        if len(a2) < 8:
            a2 = '0'*(8-len(a2))+a2
        s2.append(a2)
    return s2

def andTwo(s1,s2):
    alist = []
    for i in range(len(s1)):
        a = ''
        for j in range(8):
            a += str(int(s1[i][j]) and int(s2[i][j]))
        alist.append(a)
    return '.'.join(alist)

while True:
    try:
        result = -1
        m_10, ip1_10, ip2_10 = [i.split('.') for i in [input(),input(),input()]]
        for s in [m_10, ip1_10, ip2_10]:
            if not checklegality(s):
                result =1
        if result != 1:
            m_2, ip1_2, ip2_2 = [tenToTwo(i) for i in [m_10, ip1_10, ip2_10]]
            and1 = andTwo(m_2, ip1_2)
            and2 = andTwo(m_2, ip2_2)
            if and1 == and2:
                result = 0
            else:
                result = 2
        print(result)
    except:
        break

41. 输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数

import sys
def main():
    # sys.stdin = open('input.txt', 'r')
    while True:
        try:
            line = input().strip()
            yw = 0
            sz = 0
            space = 0
            qt = 0
            for c in line:
                if c >= 'a' and c <= 'z' or c >= 'A' and c <= 'Z':
                    yw += 1
                elif c >= '0' and c <= '9':
                    sz += 1
                elif c == " ":
                    space += 1
                else:
                    qt += 1
            print(yw)
            print(space)
            print(sz)
            print(qt)
        except:
            break

if __name__ == "__main__":
    main()

42. 称砝码

我用的是暴力求子集的方法(超时)

import sys
def backtrack(start, length, numbers, track, res):
    total = sum(track)
    if total not in res:
        res.append(total)

    for i in range(start, length):
        track.append(numbers[i])
        backtrack(i + 1, length, numbers, track, res)
        track.pop()
    return res

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    num = len(lines)
    index = 0
    while index < num:
        track = list()
        res = list()
        n = int(lines[index].strip())
        ws = list(map(int, lines[index + 1].strip().split()))
        qs = list(map(int, lines[index + 2].strip().split()))
        numbers = []

        for i, w in enumerate(ws):
            numbers += [w] * qs[i]
        length = len(numbers)
        print(numbers)
        res = backtrack(0, length, numbers, track, res)
        index += 3
        print(len(res))

if __name__ == "__main__":
    main()

这第二种方法就和labuladong的求子集的方法很相似

# 这个思路类似labuladong的求子集的第一个方法
while True:
    try:
        a = int(input())
        weight = list(map(int,input().split()))
        count = list(map(int,input().split()))
        fm,temp,ans = [],[],[0]
        # 将所有砝码放入列表
        for i in range(a):
            for j in range(count[i]):
                fm.append(weight[i])
        # 称重
        for i in fm:
            # 先改变temp
            temp = set(ans)
            # 再遍历temp,将新的砝码和前面的每一个重量进行相加,再接到temp的后面
            for j in temp:
                ans.append(j+i)
        # 去重
        print(len(set(ans)))
    except:
        break

43. 学英语

递归法可以做,但是我的英语不太好尤其是对于数字这块

def numberToWords(num):
    to19='one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen seventeen eighteen nineteen'.split()
    tens="twenty thirty forty fifty sixty seventy eighty ninety".split()
    def words(n):
        if n<20:return to19[n-1:n]
        if n<100:return [tens[n//10-2]]+words(n%10)
        if n<1000:
            return [to19[n//100-1]]+["hundred"]+["and"]+words(n%100)
        for p,w in enumerate(('thousand',"million","billion"),1):
            if n<1000**(p+1):
                return words(n//1000**p)+[w]+words(n%1000**p)
    return " ".join(words(num)) or "Zero"

def main():
    while True:
        try:
            print(numberToWords(int(input())))
        except:
            break
            
if __name__ == "__main__":
    main()

44. 迷宫问题

我一开始用的是BFS,毕竟是找最短路径吧,但是我输不出路径,只能输出走了多少步

import sys
import collections
import copy
direction = [
    (1, 0), (-1, 0), (0, 1), (0, -1)
]
def walk_the_maze(board, row, col):
    queue = collections.deque([])
    visited = []

    queue.append([0, 0])
    visited.append([0, 0])
    step = 0

    while len(queue) > 0:
        qsize = len(queue)
        for i in range(qsize):
            position = queue.popleft()
            if position == [row - 1, col - 1]:
                return step

            for d in direction:
                newposition = copy.copy(position)
                newposition[0] += d[0]
                newposition[1] += d[1]

                if not (newposition[0] >= 0 and newposition[0] < row):
                    continue
                if not (newposition[1] >= 0 and newposition[1] < col):
                    continue
                if newposition in visited or board[newposition[0]][newposition[1]] == 1:
                    continue
                else:
                    queue.append(newposition)
                    visited.append(newposition)
        step += 1

def main():
    sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    num = len(lines)
    index = 0
    while index < num:
        row_col = lines[index].strip().split()
        row = int(row_col[0])
        col = int(row_col[1])
        board = []
        for r in range(row):
            board.append(list(map(int, lines[index + 1 + r].strip().split())))
        print(walk_the_maze(board, row, col))
        index += (1 + row)


if __name__ == "__main__":
    main()

回溯法:

import sys
direction = [
    (1, 0), (-1, 0), (0, 1), (0, -1)
]
def walk_the_maze(board, row, col, position, track, res, resTrack):
    if position == [row - 1, col - 1]:
        # 更新最小步数和最短路劲
        res = min(res, len(track))
        resTrack = track.copy()
        return res, resTrack

    else:
        # 在某个位置做选择(4个方向移动的选择)
        # 当然有的移动方式不合法,要跳过
        for d in direction:
            if not (position[0] + d[0] >= 0 and position[0] + d[0] < row):
                continue
            if not (position[1] + d[1] >= 0 and position[1] + d[1] < col):
                continue
            if board[position[0] + d[0]][position[1] + d[1]] == 1:
                continue
            # 不走回头路, 在路劲中的就直接跳过
            if [position[0] + d[0], position[1] + d[1]] in track:
                continue

            else:
                track.append([position[0] + d[0], position[1] + d[1]])
                # 将移动到的位置作为下一个定点位置来选择4个方向,并接收最小步数和最短路径
                res, resTrack = walk_the_maze(board, row, col, [position[0] + d[0], position[1] + d[1]], track, res, resTrack)
                track.pop()

    return res, resTrack

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    num = len(lines)
    index = 0
    while index < num:
        row_col = lines[index].strip().split()
        row = int(row_col[0])
        col = int(row_col[1])
        board = []
        res = float('Inf')
        resTrack = []
        for r in range(row):
            board.append(list(map(int, lines[index + 1 + r].strip().split())))
        res, resTrack = walk_the_maze(board, row, col, [0, 0], [], res, resTrack)
        resTrack = map(tuple, resTrack)
        # 注意这种恶趣味的输出格式
        print('(0,0)')
        for tr in resTrack:
            print('(' + str(tr[0]) + ',' + str(tr[1]) + ')')
        index += (1 + row)


if __name__ == "__main__":
    main()

45. Sudoku-Java

import sys
def solveSudoku(board):
    n = 9
    def isVaild(r, c, number):
        for i in range(n):
            if board[r][i] == number:
                return False
            if board[i][c] == number:
                return False
            if board[(r // 3) * 3 + i // 3][(c // 3) * 3 + i % 3] == number:
                return False
        return True

    def backtrack(r, c):
        if r == n:
            return True
        if c == n:
            return backtrack(r + 1, 0)
        if board[r][c] != 0:
            return backtrack(r, c + 1)

        for number in range(1, 10):
            if not isVaild(r, c, number):
                continue

            board[r][c] = number
            flag = backtrack(r, c + 1)
            if flag:
                return True
            board[r][c] = 0

    return backtrack(0, 0)

def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    num = len(lines)
    index = 0
    while index < num:
        board = []
        for i in range(9):
            board.append(list(map(int, lines[i].strip().split())))
        flag = solveSudoku(board)
        for i in range(9):
            print(' '.join(list(map(str, board[i]))))
        index += 9

if __name__ == "__main__":
    main()

46.名字的漂亮度

import sys
from collections import Counter
def main():
    # sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    num = len(lines)
    index = 0
    while index < num:
        n = int(lines[index].strip())
        for i in range(1, n + 1):

            res = Counter(list(lines[index + i].strip()))
            res = dict(res)
            res = sorted(res.items(), key=lambda item: item[1], reverse=True)
            nn = len(res)
            ans = 0
            s = 26
            for j in range(nn):
                ans += res[j][1] * (s - j)
            print(ans)
        index += (n + 1)

if __name__ == "__main__":
    main()

47. 按字节截取字符串

import sys
# 以整数数字的形式判断一个整数是否对称
def main():
    while True:
        try:
            # 测试用例中的用例,参数是两行。而提交的代码跑的用例是一行!
            line, count = input().strip().split()
            # 获得点数
            count = int(count)
            # 初始化剩余的点数
            rest = count
            # 答案list
            ans = []
            for c in line:
                # 不是中文字符
                if not '\u4e00' <= c <= '\u9fa5':
                    # 其他字符只会消耗一个点数
                    rest -= 1
                    # 判断这次操作合理的话再append()
                    if rest < 0:
                        break
                    ans.append(c)
                # 是中文字符
                else:
                    # 中文会消耗两个点数
                    rest -= 2
                    # 判断这次操作合理的话再append()
                    if rest < 0:
                        break
                    ans.append(c)
            print(''.join(ans))
            
        except:
            break

if __name__ == "__main__":
    main()

48.从单向链表中删除指定值的节点

while True:
    try:
        s = input().split(' ')
        ls = []
        # 加入头结点
        ls.append(s[1])
        # 对s的遍历是从索引2开始的
        m = 2
        # eval(s[0])-1是因为已经加入了头结点了, 所以-1
        for i in range(int(s[0])-1):
            a,b = s[m],s[m+1]
            for j in range(len(ls)):
                if b == ls[j]:
                    # 将b插到a的后面, 插入之后b在ls的索引是j + 1
                    ls.insert(j+1,a)
                    break
                if a == ls[j]:
                    # 将a插到b的后面, a的索引是j, b的就变为了j + 1
                    ls.insert(j,b)
                    break
            m += 2
        # 删除需要删除的节点
        ls.remove(s[-1])
        print(' '.join(ls)+' ')
    except:
        break

 

你可能感兴趣的:(刷题)