HNUCM-蓝桥杯PythonB组寒假练习1

目录

1822: 六位数

2154: 饮料换购

1959: 01翻转

1965: Numbers

2155: 移动距离

2133: 魔板

2090: 神秘数列


1822: 六位数

题目描述

请编写一个程序统计在M和N之间(M (1) ABCDEF这六个数字均不相同,即A、B、C、D、E和F表示六个不同的数字。
(2) AB+CD=EF。即将这个六位数拆成三个两位数,使得第1个和第2个两位数的和等于第3个两位数。

输入

单组输入。
输入两个六位正整数M和N(M

输出

输出在M到N之间(包含M和N)满足要求的六位数的个数。

思路:简单题,按题目意思,分别判断两个条件即可。

def computed(x: int):
    boxs = []
    while x > 0:
        tmp, x = x % 10, x // 10
        if tmp in boxs:  # 说明不满足条件1
            return 0
        else:
            boxs.append(tmp)
    if boxs[0] + boxs[1] * 10 != boxs[2] + boxs[3] * 10 + boxs[4] + boxs[5] * 10:  # 说明不满足条件2
        return 0
    return 1


m, n = map(int, input().split())
cnt = 0
for i in range(m, n + 1):
    cnt += computed(i)
print(cnt)

2154: 饮料换购

题目描述

乐羊羊饮料厂正在举办一次促销优惠活动。
乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。
请你计算一下,如果小明不浪费瓶盖,尽量地参加活动。
那么,对于他初始买入的n瓶饮料,最后他一共能喝到多少瓶饮料。 

输入

输入存在多组测试数据
每组测试数据输入一行包含一个正整数n(1<=n<=10000)

输出

对于每组数据输出一行,包含一个整数,表示实际得到的饮料数

思路:通过题意,很容易发现这是一个重复的喝饮料、换饮料问题,也就是说我们可以使用递归或者递推来解决这个问题。

while True:
    try:
        n = int(input())
        cnt, cap = n, n  # cnt代表喝了多少,cap代表手上的瓶盖数量,这里表示先把n瓶喝完了
        while cap > 2:
            tmp, cap = cap // 3, cap % 3  # 换饮料
            cnt, cap = cnt + tmp, cap + tmp  # 喝饮料
        print(cnt)
    except:
        break

1959: 01翻转

题目描述

小H有个仅有01构成的n行n列矩阵。
每天小H都会选择一个子矩阵,进行01翻转操作,
即该区域状态:0->1,1->0。

输入

第1行一个整数n(1<=n<=100),表示矩阵大小。
接下来n行,表示矩阵初始状态。
第n+2行,一个整数q(1<=q<=100),表示天数。
接下来q行,每行4个整数x1,y1,x2,y2,分别表示子矩阵的左上角坐标,右下角坐标。
题目保证:1<=x1<=x2<=n,1<=y1<=y2<=n。

输出

对于每天,输出翻转操作后矩阵的状态。
(矩阵每行最后一个元素均无空格)

思路:简单的模拟题,注意输入的顺序即可。

def draw():
    x1, y1, x2, y2 = map(int, input().split())
    for i in range(x1 - 1, x2):
        for j in range(y1 - 1, y2):
            maze[i][j] = (maze[i][j] + 1) % 2
    for i in range(n):
        for j in range(n):
            print('', maze[i][j], end='') if j != 0 else print(maze[i][j], end='')
        print()
 
 
while True:
    try:
        n = int(input())
        maze = [list(map(int, input().split())) for _ in range(n)]
        q = int(input())
        while q > 0:
            q, _ = q - 1, draw()
    except:
        break

1965: Numbers

题目描述

小b打算拉着小h做一道简单的数学题,但是小h觉得太简单了,于是找到了你,相信对你来说也是小菜一碟。

具体题目为:现在有一个10进制整数122,如果转成16进制的话应该是7A,那么位数和则为17。现在题目升级为给定一个10进制整数n,需要对n转化为2~n-1进制下对应的数,并求出它们的位数和a。然后将a作为分子,n转化为不同格式数的个数作为分母b。输出最简分子式a/b

输入

第一行输入一个整数t,表示t组数据(t<=100)

接下来t行,每行输入一个10进制整数n(2

输出

输出n行,每行输出题目描述的最简分子式

思路:题目不难,就是一道进制转换加最小公约数的题目。

def computed(x: int):  # 计数位数和
    res = 0
    for y in range(2, x):
        tmp = x
        while tmp > 0:
            res, tmp = res + tmp % y, tmp // y
    return res


def fm(x: int, y: int):
    for i in range(min(x, y), 0, -1):
        if x % i == 0 and y % i == 0:
            return x // i, y // i


t = int(input())
while t > 0:
    t, n = t - 1, int(input())
    a, b = fm(computed(n), n - 2)
    print(f"{a}/{b}")

2155: 移动距离

题目描述

X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
其楼房的编号为1,2,3... 当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为6时,开始情形如下:

1  2  3  4  5  6
12 11 10 9  8  7
13 14 15 ..... 

我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离
(不能斜线方向移动)

输入

输入存在多组测试数据
输入为3个整数w m n,空格分开,都在1到10000范围内
w为排号宽度,m,n为待计算的楼号。

输出

要求输出一个整数,表示m n 两楼间最短移动距离。

思路:题目看起来有点绕,其实就是将两个楼号转换成坐标(x, y),答案就是x之间的差值的绝对值加上y之间差值的绝对值。

def arrange(x: int):
    a, b = x // w, x % w
    if b == 0:  # 正好整除,a回退一层,b回退w
        a, b = a - 1, w
    if a % 2 == 1:  # 如果是偶数层,就把b倒过来数,也就是w-b+1
        b = w - b + 1
    return a, b


while True:
    try:
        w, m, n = map(int, input().split())
        x1, y1 = arrange(m)
        x2, y2 = arrange(n)
        print(abs(x1 - x2) + abs(y1 - y2))
    except:
        break

2133: 魔板

题目描述

Rubik先生在发明了风靡全球魔方之后,又发明了它的二维版本——魔板。这是一张有8个大小相同的格子的魔板:

 
1234
8765
 

我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列1,2,3,4,5,6,7,8来表示。这是基本状态。

这里提供三种基本操作,分别用大写字母A,B,C来表示(可以通过这些操作改变魔板的状态):

A:交换上下两行;

B:将最右边的一列插入最左边;

C:魔板中央作顺时针旋转。下面是对基本状态进行操作的示范:

A:
8765
1234

B:

4123
5876

C:

1724
8635

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

输入

输入仅一行,包括8个整数,用空格分开,表示目标状态。

输出

输出文件的第一行包括一个整数,表示最短操作序列的长度。第二行为在字典序中最早出现的操作序列。

思路:通过对题目的阅读,我们不难发现,题目本质上是一个进行重复操作,然后寻找目标的问题,加上题目具有最短这一要求,所以可以确定这是一道广度优先搜索的题目。同时,我们是同字典来记录操作序列。

def a(old: str):  # A操作
    new = list(old)
    new.reverse()
    new = "".join(new)
    if boxs.get(new, -1) == -1:
        boxs[new] = boxs[old] + 'A'
        q.append(new)


def b(old: str):  # B操作
    new = old[3] + old[:3] + old[5:] + old[4]
    if boxs.get(new, -1) == -1:
        boxs[new] = boxs[old] + 'B'
        q.append(new)


def c(old: str):  # C操作
    new = old[0] + old[6] + old[1] + old[3] + old[4] + old[2] + old[5] + old[7]
    if boxs.get(new, -1) == -1:
        boxs[new] = boxs[old] + 'C'
        q.append(new)


def bfs(x: str):
    while q:
        tmp = q.pop(0)
        a(tmp), b(tmp), c(tmp)
        res = boxs.get(x, -1)
        if res != -1:  # 说明找到了目标
            print(f"{len(res)}\n{res}")
            return


order, boxs = "".join(input().split()), {"12345678": ""}
q = ["12345678"]  # 列表q用来记录源操作序列,字典boxs用来记录操作序列
bfs(order)

2090: 神秘数列

题目描述

喜欢探险的Kimi同学在一个山洞中发现了一串神秘的数,这串数的前七项如下:
1, 1, 8, 22, 85, 281, 988, ......
Kimi很想知道这个神秘数列中所蕴含的规律,你能否编写一个程序帮帮他。
当输入一个正整数N时,输出这个神秘数列第N项的值。

输入

单组输入。
输入一个正整数N,N<=50。

输出

输出神秘数列的第N项的值。

思路:这是一道规律题,一般像这种数列题都是斐波那契数列题的变种,也就是寻找当前数与之前若干个数的之间的关系,想到了就是一个公式题,没想到就是难搞了。

n, nums = int(input()), [0, 1, 1]
for _ in range(3, n + 1):
    nums.append(5 * nums[-2] + 2 * nums[-1] + 1)
print(nums[n])

你可能感兴趣的:(算法分析与设计,蓝桥杯,算法)