希冀答案算法用python语言编写

旅行商问题

【问题描述】假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

【输入形式】城市数目,以及城市之间的距离

【输出形式】所有路径之中的最小值

【样例输入】

4

0,10,15,20

10,0,35,25

15,35,0,30 

20,25,30,0


【样例输出】

80
【样例说明】

第一行说明有4个城市;第2至5行说明一个城市与其他城市的距离,其中城市到其自身的距离为0,不可达的城市之间的距离为0。

import itertools

n = int(input())  # 输入城市数目
distances = []  # 存储城市之间的距离
for i in range(n):
    row = input().split(',')
    distances.append([int(x) for x in row])

# 枚举所有可能的路径
all_paths = list(itertools.permutations(range(n)))

# 计算所有可能路径的长度
min_distance = float('inf')  # 初始化最小距离为正无穷大
for path in all_paths:
    distance = 0
    for i in range(n):
        distance += distances[path[i]][path[(i+1)%n]]  # 计算路径长度
    if distance < min_distance:
        min_distance = distance
if __name__ == '__main__':
 print(min_distance)

邮局选址问题

【问题描述】对一个以XY轴表达的城市里,n个居民点散乱分布,居民点位置可以用坐标(x,y)表示,任意两点(x1,y1)(x2,y2)间距离可以用| x1-x1|+|y1-y2|度量,居民希望在城市中选择建立邮局的最佳位置,使得n个居民点到邮局的距离总和最小

【输入形式】居民点数目,以及居民点的坐标

【输出形式】最小的距离总和

【样例输入】

3

3 3

1 6

4 9

【样例输出】9

【样例说明】第一行说明有3个居民点,第2-4行说明各个居民点的坐标

n=int(input())
lx=[]
ly=[]
for i in range(n):
    x,y=map(int,input().split())
    lx.append(x)
    ly.append(y)
lx=sorted(lx)#排序
ly=sorted(ly)
if n%2!=0:#奇数,求中位数
    z=int((n-1)/2)
    x0=lx[z]
    y0=ly[z]
else:#偶数
    z=int(n/2)
    x0=int((lx[z]+lx[z-1])/2)
    y0=int((ly[z]+ly[z-1])/2)#题目要int
sumx=0
sumy=0
for j in lx:
    p=abs(x0-j)
    sumx=sumx+p
for k in ly:
    q=abs(y0-k)
    sumy=sumy+q
print(sumx+sumy)


最优合并问题

【问题描述】给定k个排好序的序列s1,s2,,sk,用2路合并算法将这k个序列合并成一个序列。假设所采用的2路合并算法合并两个长度分别为mn的序列需要m+n-1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需要的总比较次数最少。

【输入形式】序列数目,以及各个序列中的元素数目。
【输出形式】最少的总比较次数

【样例输入】

4

5 12 11 2


【样例输出】

52


【样例说明】第一行输入说明共有4个序列,第二行说明各个序列中的元素数目。


n = int(input())
a = list(map(int, input().split(' ')))
w=int(0)
i=int(0)
a.sort()#从小到大排序
while(i<n-1):#
    w=w+a[i]+a[i+1]-1;#2个长度分别为m和n的序列需要m+n -1次比较
    a[i]=a[i]+a[i+1];
    a[i+1]=0
    i+=1
    a.sort()
print(w)
# print(b)



堆排序

【问题描述】排序问题: 给定一个无序序列,采用”堆排序“方法对序列升序排序。

【输入形式】无序的整数序列
【输出形式】升序的整数序列

【样例输入】12,11,13, 5, 6,7

【样例输出】5, 6, 7,11,12,13

【样例说明】以逗号隔开的序列, 程序内需要转化为整数序列

import heapq

def heap_sort():
    nums = input().split(",")
    nums = [int(num) for num in nums]
    heap = []
    for num in nums:
        heapq.heappush(heap, num)  # 将元素加入堆中
    sorted_nums = []
    while heap:
        sorted_nums.append(heapq.heappop(heap))  # 从堆中取出最小元素,并加入已排序列表
    print(end="")
    print(*sorted_nums, sep=",")

# 测试
if __name__ == '__main__':
 heap_sort()

布线问题

【问题描述】

印刷电路板将布线区域划分成n*m个方格,精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线。为了避免线路相交,已经布了线的方格不允许其他线穿过。对给定的电路板,找出最短的布线路径。

【输入形式】

方阵的行数、列数、布线区域方阵(其中不能通过的地方输入1,能通过的地方输入0)、起点坐标、终点坐标

【输出形式】

线路长度以及线路包含的方格坐标

【样例输入】

6 6

0 0 1 0 0 0

0 0 1 1 0 0

0 0 0 0 1 0

0 0 0 1 1 0

1 0 0 0 1 0

1 1 1 0 0 0

1 2

4 3


【样例输出】

4

1,2  > 2,2  > 3,2  > 4,2  > 4,3


【样例说明】

第1行输入方阵的行数、列数

第2-7行输入方阵元素,不能通过的地方输入1,能通过的地方输入0

第8行输入起点坐标

第9行输入终点坐标

所有元素用空格分隔, 且坐标索引从1开始!!

import numpy as np
from queue import Queue

class Node:
    def __init__(self, row, col):
        self.row = row
        self.col = col
def findPath(start, finish, n, m, grid):  # 起始点,结束点,路径长,路径
    global path, PathLen1
    if (start.row == finish.row) and (start.col == finish.col):
        Pathlen = 0
        return True
    grid[0, 0:m + 1] = grid[n + 1, 0:m + 1] = 1  # 设置四周的围墙
    grid[0:n + 1, 0] = grid[0:n + 1, m + 1] = 1
    offset = [Node(0, 1),Node(1, 0), Node(0, -1), Node(-1, 0)]  # 右,下,左,上
    NumofNbers = 4
    here = start
    nbr = Node(0, 0)
    grid[start.row][start.col] = 2
    Q = Queue(maxsize=0)  # 创建一个队列
    while True:
        for i in range(NumofNbers):  # 当前点的四周的点
            nbr.row = here.row + offset[i].row
            nbr.col = here.col + offset[i].col
            if grid[nbr.row, nbr.col] == 0:  # 该方格未被标记
                grid[nbr.row, nbr.col] = grid[here.row, here.col] + 1
                if (nbr.row == finish.row) and (nbr.col == finish.col):  # 完成布线直接结束循环
                    break
                nbr1 = Node(nbr.row, nbr.col)
                Q.put(nbr1)  # 将当前点加入队列
        if nbr.row == finish.row and nbr.col == finish.col:  # 完成布线结束循环
            break
        if Q.empty():  # 队列为空,表示无解
            return False
        here = Q.get()  # 下一个拓展结点
    Pathlen = grid[finish.row, finish.col] - 2
    PathLen1 = Pathlen
    here = finish
    for j in range(Pathlen - 1, -1, -1):  # 回溯寻找路径
        path.append(Node(here.row, here.col))  # 将当前点加入路径
        for i in range(NumofNbers):
            nbr.row = here.row + offset[i].row
            nbr.col = here.col + offset[i].col
            if grid[nbr.row, nbr.col] == j + 2:  # 找到上一个坐标
                break
        here = Node(nbr.row, nbr.col)  # 更新为上一个坐标
    return True


def main():
    global path, PathLen1

    n, m = map(int, input().split(' '))
    grid = np.zeros((n + 2, m + 2), dtype=int)

    for i in range(1, n + 1):
        grid[i, 1:n + 1] = np.array(input().split(), dtype=int)

    start_x, start_y = map(int, input().split(' '))

    finish_x, finish_y = map(int, input().split(' '))
    start = Node(start_x, start_y)
    finish = Node(finish_x, finish_y)
    if findPath(start, finish, n, m, grid):
        print(PathLen1)
        path.append(start)
        path = np.flipud(path)
        for i in range(len(path) - 1):
            print(path[i].row, end=',')
            print(path[i].col, end='-->')
        print(path[-1].row, end=',')
        print(path[-1].col)
    else:
        print("没有路径!")

global path, PathLen1
PathLen1 = 0  # 用于保存路线长度
path = []  # 保存路线
if __name__ == '__main__':
    main()

汽车加油问题

【问题描述】一辆汽车加满油后可以行驶n千米。旅途中有k个加油站。若要使沿途的加油次数最少,设计一个有效的算法,采用贪心算法,编程计算并输出最少加油次数,以及指出应在那些加油站停靠加油。

【输入形式】两行标准输入,数字通过空格分隔
【输出形式】将编程计算出的最少加油次数,以及哪些加油站,输出到文件ouput.txt。如果无法到达目的地,则输出“No Solution”。

【样例输入】            

    7 7   

    1 2 3 4 5 1 6 6                        

【样例输出】   

   4

   3 4 6 7

【样例说明】

第一行标准输入有2个正整数n和k,表示汽车加满油后可行驶n km,且旅途中有k个加油站。

第二行标准输入有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油。第k+1个加油站表示目的地。

# 这是一个示例 Python 脚本。

# 按 Shift+F10 执行或将其替换为您的代码。
# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。


def fuel(n,k,distance):#n 满油路程 k 加油站数量 distance 距离
    nTemp = n       #当前油量可行驶路程
    move=0          #将要行驶路程
    count=0         #计算加油次数
    locate=[]       #加油站坐标
    for i in range(len(distance)):
        move+=distance[i]
        if(move<nTemp):#如果下一段路程小于油量可行驶路程,则行驶
            nTemp-=distance[i]
            move=0
        else:
            nTemp=n
            nTemp -= distance[i]
            count+=1
            move=0
            locate.append(i)

    return count,locate


if __name__ == '__main__':
    # n=7
    # k=7
    # distance = [1,2,3,4,5,1,6,6]
    n, k = map(int, input().split())
    temp = input().split(" ")
    distance=list(map(int,temp))
    for i in distance:
        if (i > n):
            print("No solution!")
            exit()
    count,locate=fuel(n,k,distance)
    print(count)
    for i in locate:
        print(i,end=" ")






最大团问题

【问题描述】

给定一个无向图G=(V,E),若U为V子集,请对任意的顶点u, v为U的元素,有边(u,v)为E元素,则称U为G的一个完全子图。G的完全子图U是一个团,当且仅当U不包含在G的更大的完全子图中。G的最大团则指包含定点数最多的团。对给定的无向图,找出最大团中顶点的个数。

【输入形式】

G的邻接矩阵

【输出形式】

第一行输出最大团顶点个数,第二行输出最大团中的顶点

【样例输入】

0,1,1,0,0

1,0,1,1,1

1,1,0,1,1

0,1,1,0,1

0,1,1,1,0

【样例输出】

最大团顶点个数: 4

最大团为: [0, 1, 1, 1, 1]

【样例说明】输入的邻接矩阵表明图中有5个顶点,矩阵元素为1,则行、列对应的顶点有边相连,否则没有边相连。矩阵元素之间通过逗号隔开。举例:假设5个顶点分别为ABCDE,那么A与B、C相连。最终求得,最大团中包含4个节点,为BCDE。

import numpy as np

def bron_kerbosch_pivot(r, p, x, graph, cliques):
    if not any((p, x)):
        cliques.append(r)
    else:
        # Choose a pivot vertex u in union of p and x
        u = max(p.union(x), key=lambda v: sum(graph[v]))
        # For each vertex v in p that is adjacent to u
        for v in p.difference(graph[u]):
            # Bron-Kerbosch with pivot on v
            bron_kerbosch_pivot(r.union({v}), p.intersection(graph[v]), x.intersection(graph[v]), graph, cliques)
            # Remove v from p and add to x
            p.discard(v)
            x.add(v)

def find_cliques(graph):
    cliques = []
    bron_kerbosch_pivot(set(), set(graph.keys()), set(), graph, cliques)
    return cliques

def max_clique(graph):
    cliques = find_cliques(graph)
    max_clique = max(cliques, key=len)
    return max_clique, len(max_clique)

# 读取输入邻接矩阵
adjacency_matrix = []
while True:
    try:
        line = input().strip()
        row = list(map(int, line.split(',')))
        adjacency_matrix.append(row)
    except:
        break
graph = {i: set(np.nonzero(row)[0]) for i, row in enumerate(adjacency_matrix)}

# 求解最大团
max_clique, max_clique_size = max_clique(graph)

# 输出结果
if __name__ == '__main__':
 print("最大团顶点个数:", max_clique_size)
 print("最大团为:", max_clique)

最长公共子序列

【问题描述】

若给定序列X={x1,x2,,xm},则另一序列Z={z1,z2,,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,,ik}使得对于所有j=1,2,,k有:zj=xij。例如,序列Z={BCDB}是序列X={ABCBDAB}的子序列,相应的递增下标序列为{2357}。如果给定2个序列XY,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列XY的公共子序列。现给定2个序列X={x1,x2,,xm}Y={y1,y2,,yn},要求使用动态规划算法思想,找出XY的最长公共子序列。

【输入形式】输入以空格分割的字符,第一行对应第一条序列,第二行对应第二条序列。


【输出形式】字符数组形式的最长公共子序列。

【样例输入】

z x y

x y y


【样例输出】

['x', 'y']

【样例说明】

第一行输入为第一条序列,包含z x y三个字符;输出为最长公共子序列,包含两个字符,以数组形式输出。

def lcs(X, Y):
    m = len(X)
    n = len(Y)
    # 创建二维列表c,用于存储最长公共子序列的长度
    c = [[0] * (n+1) for _ in range(m+1)]
    # 创建二维列表b,用于记录最长公共子序列的方向
    b = [[0] * (n+1) for _ in range(m+1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if X[i-1] == Y[j-1]:
                c[i][j] = c[i-1][j-1] + 1
                b[i][j] = "↖"
            elif c[i-1][j] >= c[i][j-1]:
                c[i][j] = c[i-1][j]
                b[i][j] = "↑"
            else:
                c[i][j] = c[i][j-1]
                b[i][j] = "←"
    return c, b

def print_lcs(X, b, i, j):
    if i == 0 or j == 0:
        return []
    if b[i][j] == "↖":
        sub_lcs = print_lcs(X, b, i-1, j-1)
        sub_lcs.append(X[i-1])
        return sub_lcs
    elif b[i][j] == "↑":
        return print_lcs(X, b, i-1, j)
    else:
        return print_lcs(X, b, i, j-1)

# 测试
if __name__ == '__main__':
 X = input().split()
 Y = input().split()
 c, b = lcs(X, Y)
 lcs_result = print_lcs(X, b, len(X), len(Y))
print( lcs_result)

棋盘覆盖问题

【问题描述】给定一个2k×2k的棋盘(具体图例见教材),有一个特殊棋格,拥有一个特殊棋格的棋盘称为特殊棋盘。现要用四种L型骨牌(具体图例见教材)覆盖特殊棋盘上除特殊棋格外的全部棋格,不能重叠,找出覆盖方案。

【输入形式】在屏幕上输入棋盘大小及特殊方格所在行号和列号

【输出形式】输出使用L型骨牌进行棋盘覆盖结果

【样例输入】

2

1 2

【样例输出】

2 -1 3 3

2 2 1 3 

4 1 1 5 

4 4 5 5 


【样例说明】

输入:第一行输入整数k表示棋盘大小为2的k次幂,若k为2,则棋盘大小为4行4列;第二行输入特殊方格所在的行号和列号,以空格分隔

输出:使用L型骨牌进行棋盘覆盖结果,由3个相同的数表示同一个L型骨牌,不同的骨牌用不同的数字表示。数字的大小表示棋盘覆盖的顺序。特殊方格在棋盘的第1行第2列,用-1表示。各整数间以空格分隔。

def chessBoard(tr,tc,dr,dc,size):
    if size == 1:
        return
    global tile
    global board
    tile += 1
    t = tile
    s = size//2
    if dr<tr+s and dc<tc+s:
        chessBoard(tr,tc,dr,dc,s)
    else:
        board[tr+s-1][tc+s-1] = t
        chessBoard(tr,tc,tr+s-1,tc+s-1,s)
    if dr < tr + s and dc >= tc + s:
        chessBoard(tr, tc+s, dr, dc, s)
    else:
        board[tr+s-1][tc+s] = t
        chessBoard(tr, tc+s, tr+s-1, tc+s, s)
    if dr >= tr + s and dc < tc + s:

        chessBoard(tr+s, tc, dr, dc, s)
    else:

        board[tr + s][tc + s - 1] = t

        chessBoard(tr+s, tc, tr + s, tc + s - 1, s)


    if dr >= tr + s and dc >= tc + s:

        chessBoard(tr+s, tc+s, dr, dc, s)
    else:

        board[tr + s][tc + s] = t

        chessBoard(tr+s, tc+s, tr+s, tc+s, s)

def show_chess(board):
    n = len(board)
    for i in range(n):
        for j in range(n):
            print(board[i][j], end=" ")
        print('')


tile = 0

size = int(input())
n= pow(2,size)
if __name__ == '__main__':
 dr,dc= map(int,input().split())
board=[[0 for x in range(n)]for y in range(n)]
board[dr-1][dc-1]=-1
chessBoard(0,0,dr-1,dc-1,n)
show_chess(board)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风动跃林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值