Python刷题记录(41-50)

Python刷题记录(41-50)

题目来源PTA平台

PAT (Basic Level) Practice (中文)

@TOC


1041 考试座位号

每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。

输入格式:

输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。

考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。

输出格式:

对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。

输入样例:

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4

输出样例:

3310120150912002 2
3310120150912119 1

思路:

输入后进行匹配就完事

代码:

n = int(input())
lst = [[eval(x) for x in input().split()]for i in range(n)]
m = int(input())
M = [int(x) for x in input().split()]
for i in M:
    for j in lst:
        if i == j[1]:
            print('%d %d' % (j[0], j[2]))

1042 字符统计

请编写程序,找出一段给定文字中出现最频繁的那个英文字母。

输入格式:

输入在一行中给出一个长度不超过 1000 的字符串。字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母,以回车结束(回车不算在内)。

输出格式:

在一行中输出出现频率最高的那个英文字母及其出现次数,其间以空格分隔。如果有并列,则输出按字母序最小的那个字母。统计时不区分大小写,输出小写字母。

输入样例:

This is a simple TEST.  There ARE numbers and other symbols 1&2&3...........

输出样例:

e 7

思路:

用数组存储字母的个数,然后查找最大值输出就可

代码:

n = input().upper()
x = [0]*26
for i in n:
    if i.isupper():
        x[ord(i)-65] += 1
k = x.index(max(x))
print('%c %d' % (chr(k+97), max(x)))

1043 输出PATest

给定一个长度不超过 104 的、仅由英文字母构成的字符串。请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符。当然,六种字符的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按 PATest 的顺序打印,直到所有字符都被输出。

输入格式:

输入在一行中给出一个长度不超过 104 的、仅由英文字母构成的非空字符串。

输出格式:

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

输入样例:

redlesPayBestPATTopTeePHPereatitAPPT

输出样例:

PATestPATestPTetPTePePee

思路:

统计PATest的个数,然后只要个数不为0输出就行

虽然长但是简单

代码:

n = input()
P = n.count('P')
A = n.count('A')
T = n.count('T')
e = n.count('e')
s = n.count('s')
t = n.count('t')
while P or A or T or e or s or t:
    if P != 0:
        print('P', end='')
        P -= 1
    if A != 0:
        print('A', end='')
        A -= 1
    if T != 0:
        print('T', end='')
        T -= 1
    if e != 0:
        print('e', end='')
        e -= 1
    if s != 0:
        print('s', end='')
        s -= 1
    if t != 0:
        print('t', end='')
        t -= 1
print()

1044 火星数字

火星人是以 13 进制计数的:

  • 地球人的 0 被火星人称为 tret。
  • 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
  • 火星人将进位以后的 12 个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。

例如地球人的数字 29 翻译成火星文就是 hel mar;而火星文 elo nov 对应地球数字 115。为了方便交流,请你编写程序实现地球和火星数字之间的互译。

输入格式:

输入第一行给出一个正整数 N(<100),随后 N 行,每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文。

输出格式:

对应输入的每一行,在一行中输出翻译后的另一种语言的数字。

输入样例:

4
29
5
elo nov
tam

输出样例:

hel mar
may
115
13

思路:

输入后尝试将s转换为整型能转换将其按13进制分离出个位和十位数并输出,0单独考虑

不能转换进行匹配并转化成10进制

代码:

single = ['', 'jan', 'feb', 'mar', 'apr', 'may',
          'jun', 'jly', 'aug', 'sep', 'oct', 'nov', 'dec']
tens = ['', 'tam', 'hel', 'maa', 'huh', 'tou',
        'kes', 'hei', 'elo', 'syy', 'lok', 'mer', 'jou']

n = int(input())
for i in range(n):
    s = input()
    try:
        s = int(s)
        if s == 0:
            print('tret')
            continue
        a = s % 13  # 个位数
        b = s // 13  # 十位数
        if a == 0 or b == 0:
            rst = tens[b] + single[a]
        else:
            rst = tens[b] + ' ' + single[a]
        print(rst)

    except:
        rst = 0
        s = s.split()
        for j in s:
            if j in single:
                rst += single.index(j)
            elif j in tens:
                rst += tens.index(j) * 13
        print(rst)

1045 快速排序

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定 N = 5 N = 5 N=5, 排列是1、3、2、4、5。则:

  • 1 的左边没有元素,右边的元素都比它大,所以它可能是主元;
  • 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;
  • 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;
  • 类似原因,4 和 5 都可能是主元。

因此,有 3 个元素可能是主元。

输入格式:

输入在第 1 行中给出一个正整数 N(≤105); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 109。

输出格式:

在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

5
1 3 2 4 5

输出样例:

3
1 4 5

思路:

原本想暴力解决,但觉得太麻烦了,后来参考了柳婼大佬的思路(表示大佬真滴强,我太菜了)然后超时

后来参考了猫猫虫大佬的思路,终于通过,这里就不解释了去原作者那里看吧

https://blog.csdn.net/qq_41398808/article/details/81674374

代码:

n = int(input())
lst = [int(x) for x in input().split()]
lstsort = sorted(lst)
ans = []
for i in range(n):
    if lst[i] == lstsort[i]:
        for j in range(i):
            if lst[j] > lst[i]:
                break
        else:
            ans.append(str(lst[i]))
print(len(ans))
if len(ans) == 0:
    print()
else:
    print(' '.join(ans))

1046 划拳

划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。

下面给出甲、乙两人的划拳记录,请你统计他们最后分别喝了多少杯酒。

输入格式:

输入第一行先给出一个正整数 N(≤100),随后 N 行,每行给出一轮划拳的记录,格式为:

甲喊 甲划 乙喊 乙划

其中是喊出的数字,是划出的数字,均为不超过 100 的正整数(两只手一起划)。

输出格式:

在一行中先后输出甲、乙两人喝酒的杯数,其间以一个空格分隔。

输入样例:

5
8 10 9 12
5 10 5 10
3 8 5 12
12 18 1 13
4 16 12 15

输出样例:

1 2

思路:

输入后计算两个人喊数的和,甲对乙错乙就加一杯,甲错乙对甲就加一杯

代码:

n = int(input())
a = b = 0
for i in range(n):
    lst = [int(x) for x in input().split()]
    ans = lst[0]+lst[2]
    if lst[1] == ans and lst[3] != ans:
        b += 1
    if lst[3] == ans and lst[1] != ans:
        a += 1
print(a, b)

1047 编程团体赛

编程团体赛的规则为:每个参赛队由若干队员组成;所有队员独立比赛;参赛队的成绩为所有队员的成绩和;成绩最高的队获胜。

现给定所有队员的比赛成绩,请你编写程序找出冠军队。

输入格式:

输入第一行给出一个正整数 N(≤104),即所有参赛队员总数。随后 N 行,每行给出一位队员的成绩,格式为:队伍编号-队员编号 成绩,其中队伍编号为 1 到 1000 的正整数,队员编号为 1 到 10 的正整数,成绩为 0 到 100 的整数。

输出格式:

在一行中输出冠军队的编号和总成绩,其间以一个空格分隔。注意:题目保证冠军队是唯一的。

输入样例:

6
3-10 99
11-5 87
102-1 0
102-3 100
11-9 89
3-2 61

输出样例:

11 176

思路:

使用列表累计进行计算存储每个队的分数就行

代码:

n = int(input())
scorelst = [0]*10000
for i in range(n):
    num, score = map(str, input().split())
    dnum, ynum = map(int, num.split('-'))
    scorelst[dnum] += int(score)
print(scorelst.index(max(scorelst)), max(scorelst))

1048 数字加密

本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12;对偶数位,用 B 的数字减去 A 的数字,若结果为负数,则再加 10。这里令个位为第 1 位。

输入格式:

输入在一行中依次给出 A 和 B,均为不超过 100 位的正整数,其间以空格分隔。

输出格式:

在一行中输出加密后的结果。

输入样例:

1234567 368782971

输出样例:

3695Q8118

思路:

先将AB倒序,然后用0补全到一样长

接着按照题目的要求进行加密,最后输出即可

代码:

A, B = map(list, input().split())
A = A[::-1]
B = B[::-1]
if len(A) > len(B):
    for i in range(len(A)-len(B)):
        B.append('0')
else:
    for i in range(len(B)-len(A)):
        A.append('0')
s = ['J', 'Q', 'K']
result = ''
for i in range(len(A)):
    if i % 2 == 0:
        t = (int(A[i])+int(B[i])) % 13
        if t > 9:
            result += str(s[t-10])
        else:
            result += str(t)
    else:
        t = (int(B[i])-int(A[i]))
        if t < 0:
            t += 10
        result += str(t)
result = result[::-1]
print(result)

1049 数列的片段和

给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段。例如,给定数列 { 0.1, 0.2, 0.3, 0.4 },我们有 (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) (0.4) 这 10 个片段。

给定正整数数列,求出全部片段包含的所有的数之和。如本例中 10 个片段总和是 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0。

输入格式:

输入第一行给出一个不超过 105 的正整数 N,表示数列中数的个数,第二行给出 N 个不超过 1.0 的正数,是数列中的数,其间以空格分隔。

输出格式:

在一行中输出该序列所有片段包含的数之和,精确到小数点后 2 位。

输入样例:

4
0.1 0.2 0.3 0.4

输出样例:

5.00

思路:

原本的暴力解超时,根据网上的思路每个值的计算次数是由规律的

a[i]的次数为(i+1)*(n-i)

测试点2结果报错,改为decimal后超时,最后抄了一份代码才解决很是离谱,感觉差别并不大

查阅相关资料发现map函数的处理速度高于列表推导式,最后是循环,碰到大量数据尽量使用map来处理

代码:

from decimal import Decimal

n = int(input())
a = list(map(Decimal, input().split(' ')))
result = Decimal(0)
for i in range(n):
    result = result+a[i]*(i+1)*(n-i)
print(result.quantize(Decimal('0.00')))

1050 螺旋矩阵

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 mn 列,满足条件:m×n 等于 Nmn;且 mn 取所有可能值中的最小值。

输入格式:

输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 104,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

输入样例:

12
37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

98 95 93
42 37 81
53 20 76
58 60 76

思路:

和曾经虐过我的一道c语言题很像,这里借用了下柳婼大佬的思路和图,抄了下猫猫虫大佬的代码(虽然不是很难,但是很烦不想写了)

首先计算行数m和列数n的值,n从根号N的整数部分开始,往前推一直到1,找到第一个满足N % n== 0的,m的值等于N/n~将N个给定的值输入数组a,并将a数组中的值按非递增排序,接着建立m行n列的数组b,填充时按层数填充,一个包裹矩阵的口字型为一层,计算螺旋矩阵的层数level,如果m的值为偶数,层数为m/2,如果m为奇数,层数为m/2+1,所以level = m / 2 + m % 2;因为是从左上角第1个格子开始,按顺时针螺旋方向填充,所以外层for循环控制层数i从0到level,内层for循环按左上到右上、右上到右下、右下到左下、左下到左上的顺序一层层填充,注意内层for循环中还要控制t <= N – 1,因为如果螺旋矩阵中所有的元素已经都填充完毕,就不能再重复填充~填充完毕后,输出整个矩阵~

代码:

import math
a = int(input())
b = [int(i) for i in input().split()]
if a==1:
    print(b[0],end="")
else:
    b.sort(reverse = True)
    b=list(map(str,b))
    if math.sqrt(a)%1==0:
        m=int(math.sqrt(a))
    else:
        m =int(math.sqrt(a)+1)
    while a%m!=0:
        m+=1
    n = a//m
    matrix = [[0 for i in range(n)] for i in range(m)]
    k = 0
    i = 0
    j = 0
    l = 0
    while k<a:
        while k<a and i<n-1:
            matrix[j][i]=b[k]
            i+=1
            k+=1
        while k<a and j<m-1:
            matrix[j][i]=b[k]
            j+=1
            k+=1
        while k<a and i>l:
            matrix[j][i]=b[k]
            i-=1
            k+=1
        while k<a and j>l:
            matrix[j][i]=b[k]
            j-=1
            k+=1
        i,j,l,m,n=i+1,j+1,l+1,m-1,n-1
        if k==a-1:                    
            matrix[j][i]=b[k]
            k+=1
    for i in matrix:
        print(" ".join(i))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值