当前位置:首页>python>重磅发布:西电Python代码OJ解析(上)

重磅发布:西电Python代码OJ解析(上)

  • 2026-10-21 13:28:53
重磅发布:西电Python代码OJ解析(上)

题目请见https://python.xidian.edu.cn/problem.php?id=(题目编号,比如1000),如果这个网站关闭可以看评论区,本公众号会提供题目网站供大家查看,这里提供对应题目的代码,代码简洁,附带简单关键性解释(有些有必要一题多解的我也做了两个相对好一些的解答)  

总共90道题,OJ上题目编号不连续,所以共90个题,这一章是前50题

先导篇

在做题之前,先了解输入输出: 

(1)单行输入多个

a,b = map(int,input().split())

看到split就是把字符串分解成表格的常用办法

(2)多行输入

方法一:

a = []try:    while True:        a.append(input())except EOFError:    # 接下来输入你的代码

方法二:

import systext = sys.stdin.read()
这个是将整个文本读入text,回车以'\n'存入text
import syslines = sys.stdin.read().splitlines()
lines的类型是列表,把每一行以列表形式存入
方法三:
string = ''try:    for line initer(input, ''):        string += line + '\n'except EOFError:    string = string[0:-1]  # 去除最后的回车
这个是西电oj上给的代码,解释一下,是iter(输入,哨兵值),回车相当于若输入空字符. 个人认为有点麻烦,但既然给了,就提一下,建议用上面两种,足够
(3)输入字典,表格
a = eval(input())
eval是执行语句,执行的范围很广,所以有时候为了安全起见,用下面的(但是做oj题这个够用了哈)
import asta = ast.literal_eval(input())

支持的数据类型:字符串、数字、元组、列表、字典、布尔值、None

(4)输出: 

number = 1234.5678print(f"{number}")           # 1234.5678print(f"{number:.2f}")       # 1234.57print(f"{number:.2e}")       # 1.23e+03print(f"|{number:>10.2f}|")  # |   1234.57|print(f"{number:,.2f}")      # 1,234.57num = 123.46print(f'|{num:<10.2f}|')     # |123.46    |print(f'|{num:^10.2f}|')     # |  123.46  |print(f'|{num:0>10.2f}|')    # |0000123.46|print(f'|{num:*^10.2f}|')    # |**123.46**|

这个是规则

0. A+B problem
a, b = map(int, input().split())print(a + b)

map分配赋值,split按指定分隔符将字符串拆分成列表

1.Pyhton 的 Hello World

print("Python = Pile + sensensen")

2.python 成绩

a, b, c = map(int, input().split())d = int(a*0.2 + b*0.3 + c*0.5)print(d)

3.eval函数的使用1

a = eval(input())

4.math库的使用1

import mathprint(math.gamma(int(input())))

gamma是math模块的一个函数,是阶乘函数在实数和复数域范围的扩展.

5.字符串存在判定

a = input("")b = input("")if a in b:    print("True")else:    print("False")

in是一种常用的判断是否包含某一元素的方法

6.回文串的判断

a = input("")b = a[::-1]if a == b:    print("True")else:    print("False")

双冒号和-1让字符串倒过来

7.成绩分析

score = int(input())if score < 0 or score > 100:    print("Error!")elif score >= 90:    print("A")elif score >= 80:    print("B")elif score >= 70:    print("C")elif score >= 60:    print("D")else:    print("F")

利用elif将范围逐渐扩大

8.最大公约数

import matha = int(input())b = int(input())print(math.gcd(a, b))

gcd函数为最大公约数(当然可以自己用辗转相除法),该函数不能判断0,但oj没有设置输入0

9.输出偶数

n = int(input())for i in range(1, n+1):    if i%2 == 0:        print(i)

10.计算均值

n = int(input())b = 0for i in range(n):    b += int(input())print(f'{b}{b/n:.5f}')

f''为format,有f后里面可以为{变量}的形式,:.nf为保留n位小数

11.计算阶乘

n = int(input())a,s = 1,0for i in range(1,n+1):    a *= i    s += aprint(s)

可以使用math库里面的factorial,但是上述算法更快,无需重复计算

12.汇率兑换

s = input()if s[-1] in ['R', 'r']:    usd = eval(s[:-1])//6    print(f"{usd}D")elif s[-1] in ['D', 'd']:    rmb = eval(s[:-1])*6    print(f"{rmb}R")else:    print("Error!")

注意整除是双斜杠 //   print里面那个单位尽量按照题目,用大写

13.进度条的显示

a = int(input())print("------start------")for i in range(a+1):    p = (i/a)*100    c,d = '**'*i, '..'*(a-i)    print(f"{p:>3.0f} %[{c}->{d}]")print("------end-----")

精度:这里是指进度条进度i的范围  >3.0f表示数字占三位而且右对齐保留整数      这个题理论应当用'start'.center(scale//2,'-')   但是oj系统有bug, end不在中间,而且随着精度变化start和end这两个字符串是不会变化的,所以不如直接打

14.因字数

a = int(input())i,j = 0,0while a % 4 == 0:    a //= 4    i += 1while a % 7 == 0:    a //= 7    j += 1print(i, j)

15.文章检测

stopword,string = '',''spaces,letters,numbers,characters,others = 0,0,0,0,0try:    for line in iter(input, stopword):        str += line + '\n'except EOFError:    passstring = string[0:-1]for char in string:    if char == ' ':        spaces += 1    elif char.isdigit():        numbers += 1    elif char.isalpha():        letters += 1    else:        others += 1print(f"{spaces} spaces, {numbers} numbers, "      f"{letters} letters, {others} other characters.")

代码不难,只是很长,判断较为麻烦; 注意输出的逗号后面有空格,感兴趣的话可以使用正则表达式,利用findall查找

import re, systext = sys.stdin.read()spaces = len(re.findall(' ', text))numbers = len(re.findall('[0-9]', text))letters = len(re.findall('[A-Za-z]', text))others = len(text) - spaces - numbers - lettersprint(f"{spaces} spaces, {numbers} numbers, "      f"{letters} letters, {others} other characters.")

16.eval函数的使用2

import mathx, y = 12,14print(eval(input()))

不只是加减乘除,还有其他数学运算,必须用math库

17.质数的和与积

x = int(input())def f(a):    j = 2    while j * j <= a:        if a % j == 0:            return 0        else:            j += 1    return 1a = 1for i in range(2, x//2+1):    if f(i) and f(x-i):        if i*(x-i) > a:            a = i*(x-i)print(a)

定义判断质数的函数需要熟练掌握,非常常用  if判断非零就是成立,无需写==1

18.寻找多数元素

a = []try:    while True:        a.append(int(input()))except EOFError:    b = []    for i in a:        b.append(a.count(i))    print(max(b))

这个是最优方案,下面提供一种排序比较思维,可以了解

a = []try:    while True:        a.append(int(input()))except EOFError:    passa.sort()h = 1c = []for i in range(len(a)-1):    if a[i] == a[i+1]:        h += 1    else:        c.append(h)        h = 1c.append(h)m = max(c)print(m)

将数字排序,之后只需要比相邻数字是否相同

19.判断素数

x = input()def f(a):    j = 2    while j * j <= a:        if a % j == 0:            return False        else:            j += 1    return Trueif not x.isdigit():    print('invalid')else:    print(f(int(x)))

20.所有参数的乘积

def multi(*a):    b = 1    for i in range(len(a)):        if not isinstance(a[i], (int, float)):            return f'Invalid arg {i+1}'        else:            b *= a[i]    return bprint(eval(input()))

定义函数时,参数必须是*a,因为要接受任意数量的元素,并把它们打包成元组,(*a)的名字是可变参数,可变参数在函数中被组装成一个元组.大家注意在测试的时候要输入multi(1,'a')才可以,不能直接输入字母,直接输字母eval不出来的,默认它是个变量,会提示没有定义

21.到底怎么样才能写好 Python?

import this

22.CSV文件解析

import syslines = sys.stdin.read().splitlines()for line in lines:    print(line.replace(',', '\t') + '\t')

一般读取偏文本的格式, 并只需文本处理 用sys库更为方便

# 另一种打法 不需要sys模块a = []try:    while True:        a.append(input())except EOFError:    for x in a:        x = x.replace(',', '\t')        print(x+'\t')

23.重复元素的判定

n = int(input())b = 1a = [int(input()) for _ in range(n)]for i in range(1,n):    if a[i] in a[0:i]:        print('True')        print(i+1)        b = 0        breakif b:    print('False')

a是一个列表,这种方式更加简洁,下划线(for _ )和i是一样的

24.计算集合的并

a = set(map(int,input().split()))b = set(map(int,input().split()))print(a | b)

25.计算标准差

# method 1a = []d = 0while True:    try:        a.append(int(input()))    except EOFError:        breakc = sum(a)/len(a)for i in a:    d += (i-c)**2dev = (d/(len(a)-1))**0.5print("dev = {:.2}.".format(dev))
# method 2from statistics import stdevimport sysa = []for i in sys.stdin:    a.append(int(i))dev = stdev(a)print("dev = {:.2}.".format(dev))

求样本标准差注意分母的总数要-1,也可以用statistics模块的stdev函数

26.键值查询

data = eval(input())key = input()print(data[key])

27.月份输出

m = int(input())months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]print(months[m-1])

28.字符串进制转换

n = int(input())print(hex(n))

29.CSV 文件转换成 JSON 文件

a = []try:    while True:        a.append(input().split(','))except EOFError:    for i in range(1, len(a)):        a[i] = dict(zip(a[0], a[i]))    c = json.dumps(a[1:],sort_keys=True, indent=4)    print(c)

组装成字典: dict(zip(key的列表, value的列表))   json.dumps将对象转化为json字符串,想要达到题目效果必须对key排序,同时缩进为4个字节

30.集合的交

a = set(map(int, input().split()))b = set(map(int, input().split()))print(a & b)

31.小型登陆系统

h = 0while True:    a,b = input(),input()    c = 0    if a == 'Pile':        c += 1    if b == 'MAKIKAWAYI':        c += 1    if c == 2:        print('SUCCESS')        break    h += 1    if h == 3:        print('FAILED')        break

连续的if保证每个条件都过一遍

32.密码

# method 1n = int(input())a = [input() for _ in range(n)]for i in range(n):    b = 0    if any(c.isupper() for c in a[i]):        b += 1    if any(c.islower() for c in a[i]):        b += 1    if any(c.isdigit() for c in a[i]):        b += 1    if any(c in ['~','!','@','#','$','%','^'] for c in a[i]):        b += 1    if b >= 3 and 8 <= len(a[i]) <= 16:        print("YES")    else:        print("NO")
# method 2import reb = 0n = int(input())a = [input() for _ in range(n)]for i in a:    b = 0    if re.search('[A-Z]', i):        b += 1    if re.search('[a-z]', i):        b += 1    if re.search('[0-9]', i):        b += 1    if re.search('[~!@#$%^]', i):        b += 1    if b >= 3 and 8 <= len(i) <= 16:        print("YES")    else:        print("NO")

any括号里面需要内嵌for循环来表示对每一个元素进行遍历,节省空间; 第二种方法正则表达式直接找,可能更方便,但是是超纲内容

33.斐波那契数列Fibonacci问题

n = int(input())a = [int(input()) for _ in range(n)]m = max(a)b = [1]*(m+1)if m>=2:    b[2]=2    for i in range(3,m+1):        b[i]=b[i-1]+b[i-2]for i in range(n):    print(b[a[i]])

这个题关键在于省时间,用递归函数会重复运算,于是可以采取比较厉害的一种思路: 取最大的一个数,把每一步都记录下来,然后要求哪一步,直接输出对应步数的值就行

34.列表实现筛选法求素数

def f(x):    j = 2    while j * j <= x:        if x % j == 0:            return False        else:            j += 1    return Truea = int(input())b = 0c = []while b < 2:    if f(a):        b += 1        c.append(a)    a -= 1print(sorted(c))

35.圆周率的计算

from random import random,seedDARTS = int(input())SEED = int(input())hits = 0.0seed(SEED)for i in range(1, DARTS+1):    x, y = random(), random()    dist = pow(x ** 2 + y ** 2, 0.5)    if dist <= 1.0:        hits = hits + 1pi = 4 * (hits/DARTS)print(f'{pi:.6f}')

seed的作用: 在SEED的值不变的情况下的每次生成的随机数列完全相同

import采取from的形式,节省空间,此时不用再写'random.',直接写模块里面的函数名称就行

36.凯撒密码

a = input()n = int(input())for i in a:    if i.islower():        print(chr(ord('a') + (ord(i) - ord('a') + n) % 26), end='')    elif i.isupper():        print(chr(ord('A') + (ord(i) - ord('A') + n) % 26), end='')    else:        print(i, end='')

ord将字符转换为ASCII码, chr将ASCII码转换为字符,这里注意用end=''避免回车

37.字符串重复判断

import asta = ast.literal_eval(input())b = []char = set(a[0])for i in range(1,len(a)):    char &= set(a[i])for letter in char:    m = min(word.count(letter) for word in a)    b.append(m*letter)b = sorted(b)print('"'+''.join(b)+'"')

先用集合将相同的字符找出来,采用&=的形式比较巧, 在统计该字符出现的最少次数,都放到列表里,再排序即可

想打单引号,外侧就需要双引号,反之亦然 count表示统计个数 join是将点号前面的那个元素加到列表元素之间输出

这个题技术用得比较多,大家慢慢消化

38.卡片选择

n = int(input())a = list(map(int, input().split()))b = a.count(5)c = a.count(0)if c==0:    print(-1)elif b//9<1:    print(0)else:    print((b//9*9)*'5'+c*'0')

需要注意0也可以被9整除, 这是oj自己设计的原则,只要余数是0就可以

要注意必须写b//9*9才可以,不能写b,整除过后再×9跟原来的数字不一样

39.Life, the Universe, and Everything

# method 1a = []while True:    b = int(input())    if b == 42:        break    a.append(b)for i in a:    print(i)

上面的打法是只要输入到42就停止输入并输出42之前的数字,在oj系统是可以过的,比较简洁

但是下面这种打法更好,是正规的打法

a = []try:    while True:        a.append(int(input()))except EOFError:    for i in range(len(a)):        if a[i] == 42:            for j in a[:i]:                print(j)            break

40.23333

a, b = map(int, input().split())c = []if a == 0:    print(0)while a != 0:    d = a % b    if d < 10:        c.insert(0, d)    else:        c.insert(0, chr(ord('A') + d - 10))    a = a // bfor x in c:    print(x, end='')

上面这个代码对任何正整数(10进制)都成立,掌握更全面的更好,至于题目的23333...不用管它,太狭隘

41.整数数列求和

n,a = map(int,input().split())b = []c = [a]*nfor i in range(n):    b.append(a*pow(10,i))for i in range(1,n):    c[i] = b[i] + c[i-1]print(sum(c))

为了省时间,这个题我也用了稍微进阶一些的算法: 利用差分数组求和

c = [a]*n意思是c是一个列表,里面有n个a, 只是一个初始化,我只想让c[0]=a就行,但是要有n个元素,否则表格超范围,你写c=[a]+[0]*(n-1)也没问题.先形成b列表[2,20,200,...]通过加法实现c数组[2,22,222,..](具体你读代码就能理解),最后c数组求和即可. 序列和,差分是一种要掌握的算法

42.星号三角形

a = eval(input())//2 + 1for i in range(1, a+1):    print(' '*(a-i), end='')    print('*'*(2*i-1), end='')    print(' '*(a-i))

主要在于找规律

43.手机短号

n = int(input())a = [input() for _ in range(n)]for i in range(n):    if len(a[i]) == 11:        print('6' + a[i][-5:])    else:        print("Halation - I can't join it!")

44.aaaa+bbbb

n = int(input())lst = []def asc2(x):    c = 0    for i in range(4):        c += ord(x[i]) << (24-8*i)    return cfor j in range(n):    a,b = input().split()    lst.append(asc2(a)+asc2(b))for j in range(n):    print(lst[j])

ord表示这个字符的ASCII码 <<表示左移,这个时候是二进制,依据题目应该8位8位地去移动

45.6翻了

import rea = input()b = re.sub('6{10,}', '27', a)print(re.sub('6{4,9}', '9', b))

经典正则表达式问题,需要用到sub函数,特点是可以找字符,个数限定可以是范围 {10,}表示大于等于10

{4,9}表示6的个数是4~9个,注意左右都是闭区间

46.有理数四则运算1

from fractions import Fractiona = Fraction(input())b = Fraction(input())c = a + bprint(f'{c.numerator}/{c.denominator}')

输出用分子比分母的形式可以有效地将0输出为0/1, 事实上还不如输出0,但只有我这样输出才能过oj系统 ...当然你可以分类讨论

47.时间复杂度1

def f(x):    if x == 1:        return 0    global cnt    s = x    for i in range(2, s):        cnt += 1        if x % i == 0:            return 1    return 2if __name__ == '__main__':    a = []    try:        while True:            a.append(int(input()))    except EOFError:        b = [0,0]        n = max(a)        cnt = 0        for i in range(2, n + 1):            f(i)            b.append(cnt)        for i in a:            print(b[i])

这个题要求要高一些了,不仅到读懂代码,还要节约时间,这个节约的办法跟斐波那契数列那个题一个思路,就是取最大值,然后从表格里取出数字,因为每一个输入的数字对应cnt的值都要从2算到n

oj这个代码不是很简洁,不过还是按题目的整,只需要添加几行代码就行

48.时间复杂度2

import mathdef f(x):    if x == 1:        return 0    global cnt    s = int(math.sqrt(x))    for i in range(2, s + 1):        cnt += 1        if x % i == 0:            return 1    return 2if __name__ == '__main__':    cnt = 0    a = []    try:        while True:            a.append(int(input()))    except EOFError:        b = [0,0]        n = max(a)        for i in range(2, n + 1):            f(i)            b.append(cnt)        for i in a:            print(b[i])

49.admin 的密码问题

n = int(input())a,b,c = ['']*n,['']*n,[]alter = {'1':'@','0':'%','l':'L','O':'o'}for i in range(n):    a[i],b[i] = input().split()    for j in alter:        if j in b[i]:            b[i] = b[i].replace(j,alter[j])            if i not in c:                c.append(i)if not c:    if n == 1:        print('There is 1 account and no account is modified')    else:        print(f'There are {n} accounts and no account is modified')else:    print(len(c))    for i in c:        print(a[i],b[i])

巧用字典替换  将多个字符串存入列表,ying这题还考你单复数...

50.分级

x = int(input())a = list(map(int, input().split()))m,n = map(int, input().split())for i in range(x):    if m<=sum(a[:i])<=n and m<=sum(a[i:])<=n:        print(i+1)        break    elif i==x-1:        print(0)

这个题用卡范围的方法  虽然sum函数加了很多次但不会超时,而且时间比较短 在数字比较多的情况下,可以用下面的代码,更省时间

x = int(input())a = list(map(int, input().split()))m,n = map(int, input().split())y = 0z = sum(a)for i in range(x):    y += a[i]    if m<=y<=n and m<=z-y<=n:        print(i+2)        break    elif i==n-1:        print(0)

前50题就这样,欢迎提供更厉害的办法,感谢支持!

后40题更精彩,难度和广度总体会更高一些.

最新文章

随机文章