思特奇杯·云上蓝桥 -算法 集训营第二周

1. 带分数

题目描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字 1~9 分别出现且只出现一次(不包含 0)。
类似这样的带分数,100 有 11 种表示法。

解法一

解题思路

使用全排列将数组[1,2,3,4,5,6,7,8,9]的所有排列可能求出
在将每一种排列分成三部分a,b,c
a+b/c == n

python代码

#带分数
import itertools
def getnum(l,start,end):
    num = 0
    for i in range(start,end):
        num = num*10 + l[i]
    return num
    

if __name__ == '__main__':
    l = [1,2,3,4,5,6,7,8,9]
    ans = 0
    n = 100
    for i in itertools.permutations(l):
        for j in range(1,7):
            a = getnum(i,0,j)
            for k in range(j,len(i)-1):
                b = getnum(i,j,k+1)
                c = getnum(i,k+1,len(i))
                if a + b/c == n:
                    ans += 1
    print(ans)

运行结果
在这里插入图片描述

2. 李白打酒

题目描述

话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒 2 斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店 5 次,遇到花 10 次,已知最后一次遇到的是花,他正
好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为 a,遇花记为 b。则:
babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出
所有可能方案的个数(包含题目给出的)。

解法一

解题思路

用深度优先搜索遍历出所有可能次序
终止条件 店为0,花剩1,酒剩一斗

python代码

#李白打酒,答案14
def solution(d,f,j):
    global ans
    if d  > 0:
        solution(d-1,f,j*2)
    if f > 1:
        solution(d,f-1,j-1)
    if  d == 0 and f == 1 and j  == 1:
        ans += 1
    
if __name__ == '__main__':
    ans = 0
    solution(5,10,2)
    print(ans)

运行结果
在这里插入图片描述

3. 第 39 级台阶

题目描述

小明刚刚看完电影《第 39 级台阶》,离开电影院的时候,他数了数礼堂前的
台阶数,恰好是 39 级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上 1 个或 2 个台阶。先迈左脚,然后左右交替,最后一
步是迈右脚,也就是说一共要走偶数步。那么,上完 39 级台阶,有多少种不同
的上法呢?

解法一

深度优先搜索

python代码

'''第39 级台阶
答案51167078
'''
def dfs(n,cnt,step):
    global ans
    if cnt > n or step > n:
        return
    elif cnt == 39 and step % 2 == 0:
        ans +=  1
        return
    else:
        dfs(n,cnt+1,step+1)
        dfs(n,cnt+2,step+1)


if __name__ == '__main__':
    n = 39
    ans = 0
    dfs(n,0,0)
    print(ans)

解法二

解题思路

动态规划
定义dp1,dp2,dp1[i]表示到第i+1阶台阶刚好是奇数步有dp1[i]种走法,dp2[i]表示到第i+1阶台阶刚好是偶数步有dp2[i]种走法
可知	dp1[0] = 1,dp1[1] = 1,dp2[0] = 0,dp2[1] = 1
递推公式为
	dp1[i] = dp2[i - 1] + dp2[i - 2]
    dp2[i] = dp1[i - 1] + dp1[i - 2]

python代码

'''第39 级台阶
答案51167078
'''
def solution(n):
    dp1 = [0]*39   #存储奇数步
    dp2 = [0]*39   #存储偶数步
    dp1[0] = 1
    dp1[1] = 1
    dp2[0] = 0
    dp2[1] = 1
    for i in range(2,n):
        dp1[i] = dp2[i - 1] + dp2[i - 2]
        dp2[i] = dp1[i - 1] + dp1[i - 2]
    return dp2[-1]
if __name__ == '__main__':
    n = 39
    ans = solution(n)
    print(ans)

运行结果
在这里插入图片描述

4. 穿越雷区

题目描述

已知的地图是一个方阵,上面用字母标出了 A,B 区,其它区都标了正号或负号
分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数 瀁,表示方阵的大小, 4<=瀁<100
接下来是 瀁 行,每行有 瀁 个数据,可能是 A,B,+,-中的某一个,中间用空格
分开。
A,B 都只出现一次。
要求输出一个整数,表示坦克从 A 区到 B 区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
则程序应该输出:
10

解法一

解题思路

广度优先搜索

python代码

#穿越雷区
if __name__ == '__main__':
    n = 5
    l = [['A','+','-','+','-'],['-','+','-','-','+'],['-','+','+','+','-'],['+','-','+','-','+'],['B','+','-','+','-']]
    visited = [[False]*5 for _ in range(5)]
    ax = 0
    ay = 0
    bx = 4
    by = 0
    mVis = [[False for _ in range(n)] for _ in range(n) ]
mVis[0][0] = True
#模拟在图中上下左右走
xMove = [-1,1,0,0]
yMove = [0,0,1,-1]
#队列记录坐标和走到的次数
queue = [[0,0,0]]
while queue:
    #当走到了b点退出广搜、打印走的次数
    if mMap[queue[0][0]][queue[0][1]] == 'B':
        print(queue[0][2])
        break
    for i in range(4):
        dx = queue[0][0] + xMove[i]
        dy = queue[0][1] + yMove[i]
        if dx>=0 and dx<=n-1 and dy>=0 and dy<=n-1:
            if not mVis[dx][dy] and mMap[queue[0][0]][queue[0][1]] != mMap[dx][dy]:
                '''没有访问过并且不是连续的走-和+就可以将点加入队列'''
                queue.append([dx,dy,queue[0][2]+1])
                mVis[dx][dy] = True
    queue.pop(0)
 
if len(queue) == 0:
    """队列为空说明走不到B点"""
    print("-1")



运行结果
在这里插入图片描述

5. 迷宫

题目描述

下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以
通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它
的上、下、左、右四个方向之一。 对于上面的迷宫,从入口开始,可以按
DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向
下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行 50 列),请找
出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字
典序最小的一个作为答案。 请注意在字典序中 D<L<R<U。(如果你把以下文字
复制到文本文件中,请务 必检查复制的内容是否与文档中的一致。在试题目录
下有一个文件 瀀aze.txt, 内容与下面的文本相同)

解法一

解题思路

很明显,这是一个求最短路径的题目。这里用到的方法是 广度优先索搜。
由于在字典序中D<L<R<U,因此如果在有很多方向可以走的情况下,优先考虑往下走,走不通了在往左走,依次类推。

python代码

#迷宫,答案DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
data = '''01010101001011001001010110010110100100001000101010
          00001000100000101010010000100000001001100110100101
          01111011010010001000001101001011100011000000010000
          01000000001010100011010000101000001010101011001011
          00011111000000101000010010100010100000101100000000
          11001000110101000010101100011010011010101011110111
          00011011010101001001001010000001000101001110000000
          10100000101000100110101010111110011000010000111010
          00111000001010100001100010000001000101001100001001
          11000110100001110010001001010101010101010001101000
          00010000100100000101001010101110100010101010000101
          11100100101001001000010000010101010100100100010100
          00000010000000101011001111010001100000101010100011
          10101010011100001000011000010110011110110100001000
          10101010100001101010100101000010100000111011101001
          10000000101100010000101100101101001011100000000100
          10101001000000010100100001000100000100011110101001
          00101001010101101001010100011010101101110000110101
          11001010000100001100000010100101000001000111000010
          00001000110000110101101000000100101001001000011101
          10100101000101000000001110110010110101101010100001
          00101000010000110101010000100010001001000100010101
          10100001000110010001000010101001010101011111010010
          00000100101000000110010100101001000001000000000010
          11010000001001110111001001000011101001011011101000
          00000110100010001000100000001000011101000000110011
          10101000101000100010001111100010101001010000001000
          10000010100101001010110000000100101010001011101000
          00111100001000010000000110111000000001000000001011
          10000001100111010111010001000110111010101101111000'''
data_array = []
data_array.append([1]*52)
for i in data.split():
    data_array.append([])
    data_array[-1].append(1)
    for j in i:
        data_array[-1].append(int(j))
    data_array[-1].append(1)
data_array.append([1]*52)
visited = []  # 用来存放已经走过的点
queue = [[(1, 1)]]
start = (1, 1)
end = (30, 50)
visited.append(start)
def bfs(lst, queue, end):
    """
    广度优先搜索
    :param lst: 数据
    :param queue: 队列
    :param end: 终点坐标
    :return:
    """
    if end in queue[-1]:
        return queue
    alist = []
    for now in queue[-1]:
        row, col = now
        if lst[row+1][col] == 0 and ((row+1, col) not in visited):
            alist.append((row+1, col))
            visited.append((row+1, col))
        if lst[row][col+1] == 0 and ((row, col+1) not in visited):
            alist.append((row, col+1))
            visited.append((row, col+1))
        if lst[row-1][col] == 0 and ((row-1, col) not in visited):
            alist.append((row-1, col))
            visited.append((row-1, col))
        if lst[row][col-1] == 0 and ((row, col-1) not in visited):
            alist.append((row, col-1))
            visited.append((row, col-1))
    queue.append(alist)
    return bfs(lst, queue, end)
queue = bfs(data_array, queue, end)
Stack = []
Stack.append(start)
visited_1 = [start]
while Stack[-1] != end:
    now = Stack[-1]
    row, col = now
    i = queue[len((Stack))]
    """由于是D<L<R<U,所以尝试先走D,在走L,其次是R,U"""
    if (row+1, col) in i and (row+1, col) not in visited_1:
        Stack.append((row+1, col))
        visited_1.append((row+1, col))
        continue
    elif (row, col-1) in i and (row, col-1) not in visited_1:
        Stack.append((row, col-1))
        visited_1.append((row, col-1))
        continue
    elif (row, col+1) in i and (row, col+1) not in visited_1:
        Stack.append((row, col+1))
        visited_1.append((row, col+1))
        continue
    elif (row-1, col) in i and (row-1, col) not in visited_1:
        Stack.append((row-1, col))
        visited_1.append((row-1, col))
        continue
    else:
        """如果走不下去了,就返回"""
        Stack.pop()
length_1 = len(Stack)
strstep = ""
for i in range(1,length_1):
    if Stack[i][0] > Stack[i-1][0]:
        strstep += "D"
    elif Stack[i][0] < Stack[i-1][0]:
        strstep += "U"
    elif Stack[i][1] > Stack[i-1][1]:
        strstep += "R"
    else:
        strstep += "L"
print(strstep)

运行结果
在这里插入图片描述

6. 跳马

题目描述

中国象棋半张棋盘如图 1 所示。马自左下角(0,0)向右上角(m,n)跳。规定只能
往右跳,不准往左跳。比如图 1 中所示为一种跳行路线,并将路径总数打印出来。
在这里插入图片描述

解法一

解题思路

每一次跳马都有四种情况,将每一种情况下,x,y的变化记录在数组dx,dy
dx = [1,2,2,1]
dy = [2,1,-1,-2]
然后再用深度优先搜索遍历所有可能求解

python代码

#跳马
def dfs(x,y):
    global ans
    if x == m and y == n:
        ans += 1
        return
    for i in range(4):
        tmp_x = x + dx[i]
        tmp_y = y + dy[i]
        if tmp_x>=0 and tmp_x<=m and tmp_y>=0 and tmp_y<=n:
            dfs(tmp_x,tmp_y)
    
if __name__ == '__main__':
    dx = [1,2,2,1]  #跳马x轴上的所有变化增量
    dy = [2,1,-1,-2]  ##跳马y轴上的所有变化增量
    ans = 0
    n,m = map(int,input().split())
    dfs(0,0)
    print(ans)

运行结果
在这里插入图片描述

7. 路径之谜

8. 未名湖边的烦恼

题目描述

每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,
可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
每天早上,租鞋窗口都会排起长龙,假设有还鞋的 瀀 个,有需要租鞋的 瀁
个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的
尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种
排法)

解法一

解题思路

动态规划
设f(n,m)表示有n个人借鞋,m个 人还鞋时有f(n,m)种排列次序
而有n个人借鞋,m个 人还鞋时可表示为:有n-1个人借鞋,m个 人还鞋+有n个人借鞋,m-1个 人还鞋即
f(n,m) = f(n-1,m) + f(n,m-1)
定义数组a[n][m],其中a[i][j]表示有i个人借鞋,j个 人还鞋时有a[i][j]种排法
当没有人借鞋时,只要还鞋人数不为0都只有1种排法,即a[0][j] = 1 (1<=j<=m)
当没有人还鞋时,只有0种排法,即a[i][0] = 0 (0<=j<=m)
当借鞋人数多于还鞋人数时,有0种排法,即a[i][j] = 0 (i>j)
当借鞋人数少于还鞋人数时,a[i][j] = a[i-1][j] + a[i][j-1] (i<=j)

python代码

#未名湖边的烦恼
def solution(m,n):
    a = [[0]*(m+1) for _ in range(n+1)]#生成一个n行m列的数组初始值全为0
    for i in range(m+1):  #初始化第一行,即当解鞋人数为0时只有1种排列可能
        a[0][i] = 1
    for i in range(n+1):  #初始化第一行,即当换鞋人数为0时只有0种排列可能
        a[i][0] = 0
    print(a)
    for i in range(1,n+1):
        for j in range(1,m+1):
            if i > j:
                a[i][j] = 0
            else:
                a[i][j] = a[i-1][j] + a[i][j-1]
    print(a)
    return a[n][m]
    
if __name__ == '__main__':
    m = 3
    n = 2
    ans = solution(m,n)
    print(ans)


运行结果
在这里插入图片描述

9. 大臣的旅费

10. 2n 皇后问题

题目描述

给定一个 n*n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个
黑皇后
和 n 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,
任意的两
个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小
于等于 8。

解法一

解题思路

我们可以先放好黑皇后再放白皇后,0表示不能放皇后,1表示可以放皇后,2表示放黑皇后,3表示放白皇后。我们每放一个皇后时先检查他所在列,和两边的对角线有没有放皇后或者说是不能放皇后,判断条件是格子的数是否为一,不为一则是放了皇后或者是不能放皇后。

python代码

#2n皇后问题
def  dfs(row,n,s,mapL):
    global ans
    if row == n:#判断是否放完了 最后一行
        if s == 2:#黑皇后放完开始放白黄后,2代表黑皇后 ,3代表白皇后
            dfs(0,n,3,mapL)
        if s == 3:#全部  放完
            ans += 1
        return
    for i  in range(n):
        if mapL[row][i] != 1:#不为1、说明放了皇后,或者不能皇后
            continue
        if check(row,i,s,mapL):
            mapL[row][i] = s#可以放,将格子的数字变为放置对应皇后的数字-
            dfs(row+1,n,s,mapL)
            mapL[row][i] = 1#回溯
            
def check(row,j,s,mapL):
    r = row - 1
    k = j - 1
    for i in range(row-1,-1,-1):    #检查对应列
        if mapL[i][j] == s:
            return False
    while r>=0 and k>=0:    #检查对应左上角
        if mapL[r][k] == s:
            return False
        r -= 1
        k -= 1
    r = row -1
    k = j + 1
    while r>=0 and k<n: #检查对应右上角
        if mapL[r][k] == s:
            return False
        r -= 1
        k += 1
    return True

if __name__ == '__main__':
    n = int(input())
    mapL = [list(map(int,input().split())) for _ in range(n)]   #模拟棋盘
    '''mapL = [[1,1,1,1],
            [1,1,1,1],
            [1,1,1,1],
            [1,1,1,1]
            ]'''
    ans = 0
    dfs(0,n,2,mapL)
    print(ans)

运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 思特威(Datasheet)是一种技术文档,其主要目的是提供有关特定产品或设备的技术规格和详细信息。通过阅读思特威,用户可以了解该产品的功能、性能、尺寸、接口和电气特性等重要信息。 在思特威中,常见的内容包括产品的规格参数、功能特点、性能指标、工作条件、接口定义、电器特性、示意图以及连接示例等。这些信息对于开发人员、工程师、以及产品消费者都非常重要。工程师们可以利用思特威来了解和评估产品是否满足其需求和规格要求。消费者则可以通过思特威了解产品的功能和性能,以便做出购买决策。 思特威通常以简洁且易读的方式呈现,使用技术术语和图表来提供必要的信息。一份完整的思特威应该包括产品的物理尺寸和重量、工作电压和功率要求、接口类型和规格、传输速率、最大传输距离、环境工作温度范围、支持的协议标准等。 对于技术人员来说,思特威是他们在设计和开发产品时的重要参考资料。通过对Datasheet进行仔细研究,他们可以更好地了解产品的特性和限制,从而能够做出更好的设计决策。同时,思特威还可以作为售后服务的重要参考,提供产品的详细规格和性能信息,以便用户能够更好地了解和操作产品。 总而言之,思特威是一份技术文档,旨在提供关于特定产品的详细规格和技术信息。通过阅读思特威,用户可以全面了解产品的功能、性能和特性,以及使用该产品时的限制和条件。 ### 回答2: 思特威 datasheet 是指思特威公司产品的技术规格表。该规格表提供了关于该产品的详细信息,包括但不限于产品的规格、性能参数、接口配置、功能特点等。 在思特威 datasheet 中,首先会列出产品的基本信息,例如产品名称、型号以及适用范围等。接下来,会详细介绍产品的物理外观和尺寸,以及各个接口的类型和数量。这些信息对于用户来说非常重要,可以帮助他们了解产品的大小和适应性。 此外,datasheet中还会列出产品的性能参数,包括但不限于传输速率、工作温度范围、功耗、电压要求等。这些参数对用户来说也是至关重要的,可以帮助他们确定产品是否符合其需求。 在datasheet中,还会详细描述产品的功能特点和技术规格。例如,如果是一款网络设备,会介绍其支持的网络标准、安全功能、管理方式等。通过这些介绍,用户可以更好地了解产品的性能和功能,从而更好地评估其是否适合自己的应用场景。 综上所述,思特威 datasheet 是一份非常重要的技术规格表,提供了关于该产品的详细信息。通过阅读和理解该规格表,用户可以更好地了解产品的性能、功能和适用性,从而做出正确的购买和使用决策。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值