HNUCM-2024年春季学期《算法分析与设计》练习14

问题 A: 1的个数

题目描述

输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。

输入

输入一个整数(int类型)。

输出

这个数转换成2进制后,输出1的个数。

样例输入 Copy

5

样例输出 Copy

2

while True:
    n=int(input())
    m=bin(n)
    a=list(m)
    number=0
    for i in a:
        if i=='1':
            number+=1
    print(num)

 问题 B: 又一道简单题

题目描述

输入一个四个数字组成的整数 n,你的任务是数一数有多少种方法,恰好修改一个数字,把它 变成一个完全平方数(不能把首位修改成 0)。比如 n=7844,有两种方法:3844=622 和 7744=882。

输入

输入第一行为整数 T (1<=T<=1000),即测试数据的组数,以后每行包含一个整数 n (1000<=n<=9999)。 

输出

对于每组数据,输出恰好修改一个数字,把 n变成完全平方数的方案数

样例输入 Copy

2

7844

9121

样例输出 Copy

Case 1: 2

Case 2: 0

def check(x: int, y: int):
    tmp = 0
    while x > 0:
        tmp = tmp + 1 if x % 10 != y % 10 else tmp
        x, y = x // 10, y // 10
    if tmp == 1:
        return 1
    else:
        return 0
t, cnt = int(input()), 0
while t> cnt:
    cnt, n, res = cnt + 1, int(input()), 0
    for i in range(32, 100):
        res = res + check(i ** 2, n)
    print(f"Case {cnt}: {res}")

问题 C: 安置路灯

题目描述

小Q正在给一条长度为n的道路设计路灯安置方案。

为了让问题更简单,小Q把道路视为n个方格,需要照亮的地方用'.'表示, 不需要照亮的障碍物格子用'X'表示。

小Q现在要在道路上设置一些路灯, 对于安置在pos位置的路灯, 这盏路灯可以照亮pos - 1, pos, pos + 1这三个位置。

小Q希望能安置尽量少的路灯照亮所有'.'区域, 希望你能帮他计算一下最少需要多少盏路灯。

输入

输入的第一行包含一个正整数t(1 <= t <= 1000), 表示测试用例数 接下来每两行一个测试数据, 第一行一个正整数n(1 <= n <= 1000),表示道路的长度。 第二行一个字符串s表示道路的构造,只包含'.'和'X'。

输出

对于每个测试用例, 输出一个正整数表示最少需要多少盏路灯。

样例输入 Copy

2

3

.X.

11

...XX....XX

样例输出 Copy

1

3

t=int(input())
while t>0:
    n=int(input())
    s=str(input())
    s=list(s)
    count,i=0,0
    while i<n:
        if s[i]=='.':
            count+=1
            i+=3
        else:
            i+=1
    print(count)
    t-=1

 问题 D: 单源最短路径问题

题目描述

编程实现Dijkstra算法,求一个有向加权图中,从源点出发到其他各个顶点的最短路径。

输入

第1行第1个值表示顶点个数,第2个值表示边个数;第2行开始为边(两个顶点,边的起点和终点)及权重。

输出

顶点0到每一个顶点的最短路径长度。

样例输入 Copy

5 7

0 1 10

0 3 30

0 4 100

1 2 50

2 4 10

3 2 20

3 4 60

样例输出 Copy

0 10 50 30 60

while True:
    n,m=map(int,input().split())
    k=[[float("inf") for i in range(n)] for j in range(n)]
    for i in range(m):
        a,b,c=map(int,input().split())
        k[a][b]=c
    d=[float("inf") for i in range(n)]
    d[0]=0
    t=0
    u=[0 for i in range(n)]
    for i in range(n):
        maxlen=float("inf")
        for j in range(n):
            if u[j]!=1 and d[j]<maxlen:
                maxlen=d[j]
                t=j
        u[t]=1
        for i in range(n1):
            if u[i]!=1 and d[t]+k[t][i]<d[i]:
                d[i]=d[t]+k[t][i]
    for x in d:
        print(x,end=" ")
    print()

 问题 E: ABC + DEF = GHI

题目描述

用1, 2, 3...9 这九个数字组成一个数学公式,满足:ABC + DEF = GHI,每个数字只能出现一次,编写程序输出所有的组合。

输入

输出

输出所有的 ABC + DEF = GHI,
每行一条数据,格式为ABC+DEF=GHI
输出结果按照ABC升序排列,如果ABC相同,则按照DEF升序排列

s=[int(i) for i in range(1,10)]
a=[False]*9
def dfs(step):
    if step==9:
        if s[0]*100+s[1]*10+s[2]+s[3]*100+s[4]*10+s[5]==s[6]*100+s[7]*10+s[8]:
            x=s[0]*100+s[1]*10+s[2]
            y=s[3]*100+s[4]*10+s[5]
            z=s[6]*100+s[7]*10+s[8]
            print(f"{x}+{y}={z}")
    for j in range(1,10):
        if a[j-1]==False:
            s[step]=j
            a[j-1]=True
            dfs(step+1)
            a[j-1]=False
dfs(0)

 问题 F: 油田问题

题目描述

输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),即属于同一个八连块。

输入

多组输入
输入行数m,以及列数n。
然后输入*和@
1<=n,m<=100

输出

联通块个数

样例输入 Copy

5 5

****@

*@@*@

*@**@

@@@*@

@@**@

样例输出 Copy

2

import sys
sys.setrecursionlimit(100000)
def slove(r,c,id):
    if r<0 or r>=m or c<0 or c>=n:
        return
    if idx[r][c]>0 or pic[r][c]!='@':
        return
    idx[r][c]=id
    for dr in range(-1,2):
        for dc in range(-1,2):
            if dr!=0 or dc!=0:
                slove(r+dr,c+dc,id)
while True:
    m,n=map(int,input().split())
    idx=[[0]*n for _ in range(m)]
    pic=[]
    for i in range(m):
        pic.append(list(input()))
    cnt=0
    for i in range(m):
        for j in range(n):
            if idx[i][j]==0 and pic[i][j]=='@':
                cnt+=1
                slove(i,j,cnt)
                
    print(cnt)

 问题 G: 迷宫问题(回溯法)

题目描述

输入一个n×n的迷宫,定义左上角为起点,右下角为终点,寻找一条从起点到终点的路径

输入

多组输入
每组输入第一行有两个整数n,m表示迷宫尺寸
后跟n行,每行m个字符0表示道路,1表示墙壁
1<=n,m<=10

输出

输出地图,用2表示路径
多个答案输出任意一种即可

样例输入 Copy

5 5

0 1 1 1 1

0 0 0 0 1

1 1 1 0 1

0 0 0 0 1

0 1 1 0 0

样例输出 Copy

2 1 1 1 1

2 2 2 2 1

1 1 1 2 1

0 0 0 2 1

0 1 1 2 2

def dfs(x, y):
    if x == n - 1 and y == m - 1:
        paths.append(path[:])
        return
    else:
        for t in d:
            fx, fy = x + t[0], y + t[1]
            if 0 <= fx < n and 0 <= fy < m and maze[fx][fy] == 0:
                maze[fx][fy]= 2
                path.append((fx, fy))
                dfs(fx, fy)
                maze[fx][fy]= 0
                path.pop()
        return
 
 
d = [(-1, 0), (1, 0), (0, -1), (0, 1)]
while True:
    try:
        n, m = map(int, input().split())
        maze, paths, path = [[int(i) for i in input().split()] for _ in range(n)], [], [(0, 0)]
        dfs(0, 0)
        for i, j in paths[0]:
            maze[i][j] = 2
        for i in range(n):
            for j in range(m):
                if j!= 0:
                    print('', maze[i][j], end='')
                else:
                    print(maze[i][j], end='')
            print()
    except:
        break

 问题 H: 低碳出行

题目描述

为了做一项关于“爱护环境,从小做起”的公益调查,新司机小明决定开老爸的车从家中前往X市第一小学。从小明家到X市第一小学的交通网络图一共有n个顶点(包括起点小明家和终点X市第一小学)和m条无向边。每条边都有一个碳排放量和一个行驶时间(单位:分钟)。
现在需要你编写一个程序帮助小明实现低碳出行,即寻找一条碳排放量最少的路径,一条路径的碳排放量等于该路径上所有边的碳排放量之和。如果存在两条碳排放量相同的路径,则找出总的行驶时间最少的路径,并输出该路径的总碳排放量和总的时间(分钟)。

输入

单组输入。
在每组输入中,第1行包含两个正整数n和m,分别表示顶点数和边数(n<=1000且m<=1000)。其中,第1号顶点为起点(小明家),第n号顶点为终点(X市第一小学)。两个正整数之间用空格隔开。
第2行到第m+1行表示m条边的信息,每一行包含四个正整数。第1个正整数和第2个正整数表示一条边所对应的两个顶点的编号,第3个正整数表示该边对应的碳排放量,第4个正整数表示该边所对应的行驶时间(单位:分钟)。四个正整数两两之间用空格隔开。

输出

对于每组输入,输出碳排放量最少的路径的总碳排放量和总时间(分钟),如果存在两条碳排放量相同的路径,则输出总的行驶时间最少的路径的总碳排放量和总时间。

样例输入 Copy

3 3

1 2 5 5

1 3 8 11

2 3 3 5

样例输出 Copy

8 10

def dijkstra(s: int, t: int):
    visited, co, ti = [False] * (n + 1), [0] * (n + 1), [0] * (n + 1)
    for i in range(1, n + 1):
        co[i], ti[i] = co2[s][i], tim[s][i]
    co[s], ti[s], visited[s] = 0, 0, True
    for i in range(n - 1):
        index, min_co2, min_time = 0, float('inf'), float('inf')
        for j in range(1, n + 1):
            if not visited[j] and (co[j] < min_co2 or (co[j] == min_co2 and ti[j] < min_time)):
                min_co2, min_time, index = co[j], ti[j], j
        visited[index] = True
        for v in range(1, n + 1):
            tmp_co2, tmp_time = co[index] + co2[index][v], ti[index] + tim[index][v]
            if not visited[v] and (tmp_co2 < co[v] or (tmp_co2 == co[v] and tmp_time < ti[v])):
                co[v], ti[v] = tmp_co2, tmp_time
    print(co[t], ti[t])
 
 
n, m = map(int, input().split())
co2, tim = [[float('inf')] * (n + 1) for _ in range(n + 1)], [[float('inf')] * (n + 1) for _ in range(n + 1)]
for _ in range(m):
    a, b, c, d = map(int, input().split())
    co2[a][b] = co2[b][a] = min(c, co2[a][b])
    tim[a][b] = tim[b][a] = min(d, tim[a][b])
dijkstra(1, n)

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您讲解一下 HNUCM 最小生成树(Prim)的算法过程。 首先,Prim 算法是一种贪心算法,用于求解带权无向连通图的最小生成树。下面是具体的算法过程: 1. 选取任意一个顶点作为起点,将其加入到生成树中。 2. 找到与已经加入到生成树中的顶点相邻的所有顶点,并计算它们与生成树的距离。 3. 从这些顶点中选取距离最小的顶点,将其加入到生成树中。 4. 重复步骤2和3,直到生成树中包含了所有的顶点。 在具体实现时,可以使用一个数组来记录每个顶点是否已经加入到生成树中,以及另一个数组来记录每个顶点与生成树的距离。每次选择距离最小的顶点时,可以使用一个最小堆来优化。 至于 HNUCM 最小生成树 Prim 算法的具体实现,可以参考以下代码: ```python import heapq def prim(graph): n = len(graph) visited = [False] * n distance = [float('inf')] * n distance[0] = 0 heap = [(0, 0)] result = 0 while heap: (d, u) = heapq.heappop(heap) if visited[u]: continue visited[u] = True result += d for v, weight in graph[u]: if not visited[v] and weight < distance[v]: distance[v] = weight heapq.heappush(heap, (weight, v)) return result ``` 这段代码实现了 HNUCM 最小生成树 Prim 算法的过程,其中 graph 是一个邻接表表示的带权无向连通图,每个元素是一个二元组 (v, w),表示从节点 u 到节点 v 有一条边权为 w 的边。算法的返回值是最小生成树的总权值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值