记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。

报名快要截止了,明年3月份考试,开始做一下准备吧,做题之余拿出来一点时间记录一下,也方便以后复习的时候回忆,也希望和更多的大佬们一起交流,相互学习
题目来源:南京信息工程大学OJ平台https://acm.nuist.edu.cn/problem

文章目录

    • 1.Python多组输入问题
    • 2.最大公约数
    • 3.数据合并
    • 4.搭梯子问题
    • 5.走出泥潭
    • 6.开灯问题
    • 7.移动小球
    • 8.小数乘法
    • 9.移动小球算法优化
    • 10.棋盘最优路径问题
    • 11.排序问题
    • 12.数的距离差
    • 13.字符串统计
    • 14.长整数加法

1.Python多组输入问题

多组输入,两整数求和。

while True:
    try:
        a, b = map(int, input().split())
        print(a + b)
    except:
        break

不要忘记添加try语句抛出异常,否则,本人在某oj平台上测试会显示runtime error

2.最大公约数

题目描述
给定 2个数,a和 b (3

输入描述
多组输入,输入的第一行为一个正整数 n,表示接下来有 n 组数据,每一行为两个正整数 a,b (3

输出描述
对于每一组数据,求出 a 和 b 的最大公约数。
样例输入

2
2 4
3 5

样例输出

2
1

准备工作:
求最大公约数算法:

辗转相除法

有两整数a和b:

① a%b得余数c

② 若c=0,则b即为两数的最大公约数

③ 若c≠0,则a=b,b=c,再回去执行①

例如求27和15的最大公约数过程为:
因此,3即为最大公约数。

n = int(input())

for i in range(n):
    
    a, b = map(int, input().split())
    c = a % b
    while c != 0:
        a = b
        b = c
        c = a % b
    print(b)

3.数据合并

题目描述

将两个从小到大排列的一维数组 (维长分别为 m,n,其中 m,n≤100) 仍按从小到大的排列顺序合并到一个新的一维数组中,输出新的数组.

输入描述
第 1 行一个正整数 m , 表示第一个要合并的一维数组中的元素个数
第 2 行一个正整数 n , 表示第二个要合并的一维数组中的元素个数
第 3 行输入 m 个整数 (每个数用空格分开) , 表示第一个数组元素的值.
第 4 行输入 n 个整数 (每个数用空格分开) , 表示第二个数组元素的值.

输出描述
一行,表示合并后的数据,共 m+n个数

样例输入

3
4
1 3 5
2 4 6 8

样例输出

1 2 3 4 5 6 8
m = int(input())
n = int(input())

s_m = list(map(int, input().split()))
s_n = list(map(int, input().split()))
s = s_m + s_n
s.sort()
for i in range(m + n - 1):
    print(s[i], end=' ')
print(s[m + n - 1], end='')

4.搭梯子问题

题目描述

用一堆宽度一致的木条,开始搭梯子。

一个良好的 k 阶梯子应满足如下两个要求:

  1. 有 2 根长度至少为 k+1 的木条,用作梯子两侧的边 (梯子的两边之间距离确定为 1)。
  2. 有 k 根长度至少为 1 的木条,用作梯子的阶梯。

红线上方是满足条件的梯子,下方是不满足条件的梯子:
记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。_第1张图片
输入描述

第一行包含一个整数 T(1⩽T⩽10),表示询问的次数(每次询问都是独立的)。
每次询问都有两行输入:
第一行输入整数 n(2⩽n⩽105),表示木条的数量。
第二行输入 n 个数:a1,a2,⋯ ,an(1⩽ai⩽109),表示木条的长度。

输出描述
输出 T 个数字,每个数字一行,表示在当前状况下能搭出的梯子的最大阶数 k 。如果当前连 1 阶都搭不了,输出 0。
样例输入

4
4
1 3 1 3
3
3 3 2
5
2 3 3 4 2
3
1 1 2

样例输出

2
1
2
0
T = int(input())
num = 0

for i in range(T):
    n = int(input())
    length = list(map(int, input().split()))
    length.sort()
    second = length[n-2]
    print(min(n-2, second-1))

5.走出泥潭

泥潭只有一条穿越路线,且对于 n×\times×m 的地图,路线长度为 n+m-1
输入描述

两个整数 n 和 m,表示泥潭的长和宽。下面 n 行 m 列表示地形(0 表示泥潭,1 表示落脚点)

输出描述

用坐标表示穿越路线,坐标之间用 > 分隔

样例输入

6 9
1 1 1 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 1 1 0 0 0
0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 1

样例输出

(1,1)>(1,2)>(1,3)>(2,3)>(2,4)>(2,5)>(3,5)>(4,5)>(4,6)>(5,6)>(5,7)>(5,8)>(5,9)>(6,9)
m, n = map(int, input().split())
arr = [[] for i in range(m)]
# 二位数组的输入
for i in range(m):
    line = input().split()
    for j in range(n):
        arr[i].append(int(line[j]))

for i in range(m):
    for j in range(n):
        if arr[i][j] == 1:
            if i == m - 1 and j == n - 1:
                print('(%d,%d)' % (i+1, j+1), end='')
            else:
                print('(%d,%d)' % (i+1, j+1), end='>')

运行结果
记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。_第2张图片
oj上测试就是不通过,不清楚到底啥原因!!?

6.开灯问题

有 n 盏灯,编号为 1∼n. 第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关 (这些灯被关掉) , 第 3 个人按下所有编号为 3 的倍数的开关 (其中关掉的灯将被打开,打开的将被关掉) , 依次类推。一共有 k 个人,问最后有哪些灯开着?

样例输入

7 3

样例输出

1
5
6
7

解题代码

while True:
    try:
        n, k = map(int, input().split())
    except:
        break
    # 0 represent turn off but 1 represent turn up
    bulb_state = [0 for i in range(n)]
    
    for i in range(k):
        for j in range(n):
            if (j+1) % (i+1) == 0:
                if bulb_state[j] == 0:
                    bulb_state[j] = 1
                else:
                    bulb_state[j] = 0

    for i in range(n):
        if bulb_state[i] == 1:
            print(i+1)

运行结果
记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。_第3张图片

7.移动小球

你有一些小球,从左到右依次编号为 1,2,3,…,n,(1<=n,m<=2000)

你可以执行两种指令。A X Y 把小球 X 移动到 Y 左边;B X Y 把小球 X 移动到 Y 右边。指令保证合法(X 与 Y 不同)。

样例输入

6 2

A 1 4

B 3 5

样例输出

2 1 4 5 3 6
def left_x(x, y):
    for i in range(n):
        if num[i] == x:
            for j in range(n):
                if num[j] == y:
                    num.remove(num[i])
                    num.insert(j-1, x)


def right_x(x, y):
    for i in range(n):
        if num[i] == x:
            for j in range(n):
                if num[j] == y:
                    num.remove(num[i])
                    num.insert(j+1, x)


while True:
    try:
        n, m = map(int, input().split())
        num = [i + 1 for i in range(n)]

        for i in range(m):
            instruction = list(input().split())
            if instruction[0] == 'A':
                left_x(int(instruction[1]), int(instruction[2]))
            else:
                right_x(int(instruction[1]), int(instruction[2]))

        for i in range(n - 1):
            print(num[i], end=' ')
        print(num[n - 1])
    except:
        break

结果没毛病,OJ提交时超。left_x()和right_x()时间复杂度O(n2),找时间再去改进一下,今天周六,先这样吧。。。。。。
记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。_第4张图片
昨天周末偷了个懒,今天周一,继续更新

8.小数乘法

题目描述
一般来说两个小数相乘所得的积仍然是小数,从键盘上输入两个双精度浮点数,求它们相乘所得的积的小数部分,结果保留 5 位小数(最后一位四舍五入)。

输出描述
占一行,对于输入的每组两个数相乘所得的积的小数部分(保留 5 位小数)
样例输入

1.233 2.345

3.5 4.78

样例输出

0.89139

0.73000
while True:
    try:
        a, b = map(float, input().split()) # Python中无double类型,只有float
    except:
        break
    result = a * b
    result = result - int(result)
    print('%.5f' % result)


注意Python中的round()函数,未必真正做到四舍五入,详情可以参考
上海_彭彭(用两种方法解决round 遇5不进)

9.移动小球算法优化

while True:
    k = 0
    try:
        n, m = map(int, input().split())
        left = [i - 1 for i in range(n+2)]
        right = [i + 1 for i in range(n+2)]
        for i in range(m):
            instruction = list(input().split())
            a = int(instruction[1])
            b = int(instruction[2])
            right[left[a]] = right[a]
            left[right[a]] = left[a]
            if instruction[0] == 'A':
                left[a] = left[b]
                right[a] = b

                right[left[b]] = a
                left[b] = a
            else:
                left[a] = b
                right[a] = right[b]

                left[right[b]] = a
                right[b] = a
        for i in range(n-1):
            k = right[k]
            print(k, end=' ')
        print(right[k])
    except:
        break

上一个算法时间2912ms,这个算法1139ms
OJ平台用c++写,与这个算法思想相同,可以通过,改成Python后却超时(时限1s),Why!?

10.棋盘最优路径问题

题目描述
小米现在来到了阿兹特克宝藏堆中。这些宝藏散落放在一个 m * n 的网格上,每个宝藏都有一个价值。小米自然是希望将所有宝藏统统拿走,但他在走出迷宫时,不小心中了魔咒,一次只能向下或向右移动一步。假设 小米 身处网格的左上角,而古城的出口在右下角,他想在离开古城前,拿到价值之和尽可能大的宝藏。请你编写程序,帮助他计算他可以拿到的最大价值之和。

样例输入

3 4

0 5 2 3

4 5 6 7

8 9 10 11

样例输出

42

其实这是一个动态规划问题,关键步骤是求出状态转移方程。
现在生成一个大小为m*n的矩阵price,price[[i][j]的含义为从(0,0)点到(i,j)点的最大路径
显然 第一行(列)的路径值就为从0,0点到i,j每一点值的和

0 5 7 10

4 

12

置price[0][0] = 矩阵值[0][0]; 对于第一行来说price[i][0] = price[i-1][0]+矩阵值[i][0];对于第一列来说 price[0][i] = price[0][i-1]+矩阵值[0][i];

对于除第一行第一列之后其他的位置有price[i][j] = max(price[i-1][j],price[i][j-1])+矩阵值[i][j];

至此,状态转移方程求解完毕

# 动态规划问题

while True:
    try:
        m, n = map(int, input().split())
        price = [[] for i in range(m)]
        for i in range(m):
            line = input().split()
            for j in range(n):
                price[i].append(int(line[j]))

        for i in range(n - 1):  # 第一行的值
            price[0][i + 1] += price[0][i]

        for i in range(m - 1):  # 第一列的值
            price[i + 1][0] += price[i][0]

        for i in range(m - 1):
            for j in range(n - 1):
                price[i + 1][j + 1] += max(price[i][j + 1], price[i + 1][j])  # 状态转移方程
        print(price[m-1][n-1])
    except:
        break

OJ完美通过

关于动态规划的详细介绍参考链接will的猜想

11.排序问题

输入描述

第一行是一个整数 n(0

输出描述

共 n 行,即排序后的 NBA 总冠军队伍。每行先是时间,后是城市名。

样例输入

4
Boston 1963
Boston 1959
Philly 1947
New York 1970
6
Los Angeles 2000
Miami 2006
Boston 1964
Los Angeles 2000
Boston 1965
Los Angeles 2002

样例输出

1947 Philly

1959 Boston

1963 Boston

1970 New York

1964 Boston

1965 Boston

2000 Los Angeles

2002 Los Angeles

2006 Miami
def take_second(arr):
    return arr[-1]


while True:
    try:
        n = int(input())
        nba_queue = []
        for i in range(n):
            nba_queue.append(input().split())
        nba_queue.sort(key=take_second)
        for i in range(n):
            print(nba_queue[i][-1], end=' ')
            for temp in nba_queue[i]:
                if temp == nba_queue[i][-1]:
                    print()
                    break
                print(temp, end=' ')
    except:
        break

没搞懂,OJ又报错…emmmmmm…
运行结果
记录第一次参加蓝桥杯Python组做题经过,小白起步,每天更新,欢迎交流。_第5张图片

12.数的距离差

题目描述

给定一组正整数,其中的最大值和最小值分别为 max 和 min,其中的一个数 x 到 max 和 min 的距离差 D 定义为 abs (abs (x - max) - abs (x - min))。其中,abs () 表示求一个数的绝对值。

输入描述

第一行为一个整数 T,表示测试数据的组数。

每组测试数据占一行,为一组以空格分隔的整数。

其中第一个整数 n(n <= 100)表示该组中正整数的个数,接下来的 n 个正整数为该组输入。

输出描述

每组测试数据输出一行,其值为使得距离差 D 最小的 x。

样例输入

2

5 3 1 7 5 9

8 11 9 7 15 6 19 12 10

样例输出

5

12
n = int(input())
D = float('inf')
min_j = 0
for i in range(n):
    arr = list(map(int, input().split()))
    arr.pop(0)
    arr.sort()
    for j in range(len(arr) - 2):
        min_D = abs(abs(arr[j+1] - arr[len(arr) - 1]) - abs(arr[j+1] - arr[0]))
        if min_D < D:
            D = min_D
            min_j = j+1
    print(arr[min_j])
    min_j = 0
    D = float('inf')

OJ完美通过

13.字符串统计

题目描述

统计一段英文文字中指定字符的个数。

输入描述

每组测试数据包括 2 行,第一行为一段英文文字 (长度小于 100),第二行为待统计的字符。

输出描述

每组测试数据输出一行,为文字中指定字符的个数。

样例输入

AaBbABC

A

AAB BABC

a

样例输出

2

0
while True:
    num = 0
    var = input()
    if var == '':
        break
    aim = input()
    num = var.count(aim)
    print(num)

完美运行 OJ报RunTime Error 实在搞不懂为什么 遇到好多次这样的结果了,emmmmmm…
慢慢去发现吧,是我的问题还是OJ的问题

14.长整数加法

题目描述

给定 2 个正整数 a,b, a 和 b 最多可能有 40 位,求出 a+b 的和。
输入描述

两个正整数 a,b,a 和 b 最多可能有 40 位。一行表示一个数。
输出描述

a+b 的和。
样例输入

111111111111111111111111111111111111111
222222222222222222222222222222222222222

样例输出

333333333333333333333333333333333333333
def change_length(arr, l):
    arr = '0' * (l - len(arr)) + arr
    return arr


arr = input()
arr_2 = input()

if len(arr) > len(arr_2):
    arr_2 = change_length(arr_2, len(arr))
elif len(arr) < len(arr_2):
    arr = change_length(arr, len(arr_2))

result = [0 for i in range(len(arr) + 1)]
k = 0
for i in range(len(arr)):
    rs = k + int(arr[len(arr) - i - 1]) + int(arr_2[len(arr_2) - i - 1])
    result[len(arr) - i] = rs % 10
    k = 0
    if rs >= 10:
        k = int(rs / 10)

if k != 0:
    result[0] = k
    for i in range(len(result) - 1):
        print(result[i], end='')
    print(result[-1])
else:
    for i in range(len(result) - 2):
        print(result[i+1], end='')
    print(result[-1])

你可能感兴趣的:(蓝桥杯,Python,OJ)