大鹏

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

 

"""
先声明思路是学“冲就完事”博主的题解的(“真正python 迷宫最短路径解法(华为机试)”),
把原帖贴上:https://blog.nowcoder.net/n/a3e0ea7fbf3746f6b342fe0d26d7fd5b?f=comment
他的代码很详细,大家可以去琢磨一下他的思路。

很好的一道递归题,下面先对递归做个小总结。
首先递归就是函数自己调用自己,当然要有结束嵌套的情况,不能一直调用。函数调用的情况可以看作是压栈,最后调用的那一次先有结果或返回,然后返回倒数第二次,最后返回到最初的函数调用。

那么遵循以上原则,对此题思路做个解释。

首先是有迷宫的输入,此外我们对路劲和走过的点要做记录,这里设为path,points。
然后就是函数部分,我们有起点(0,0),这个作为最初的函数输入,进入函数后第一步先判断下一个可以走的点和把当前点记作走过的点,我们为了简洁递归里的代码段,再嵌套一个寻找下一个点的函数,返回的是下一个可能的点的集合k(以序列的形式),然后如果没有下一个可能的点了(也就是路堵死了),就结束函数,如果有下一个点的可能,则让路径添加该点,判断是否到达了终点。如果到达了,则判断路径长度是否最短,最短的话则把结果路径修改(res),否则不变。没有的话,对路径和走过的点进行一个浅复制,递归调用函数。
在函数返回的时候,如果在返回的点处还有另外可能的点,则修改路径的最后一项(也就是该点第一次选择的路)。可以这样修改的原因是浅复制,后续调用的时候不会改变当前路径的记录,详细想了解的可以去搜浅复制。
"""

while True:
    try:
        n, m = [int(x) for x in input().split()]

        maze = []

        for i in range(n):
            maze.append([int(x) for x in input().split()])

        points = []
        for i in range(n):
            points.append([])
            for j in range(m):
                points[i].append(0)

        path = []

        def get_points(i,j,maze,points):
        #     print('test3',i,j)
            k = []
            if(0 <= i+1 < n and maze[i+1][j] == 0 and points[i+1][j] == 0):
                k.append([i+1,j])
            if(0 <= i-1 < n and maze[i-1][j] == 0 and points[i-1][j] == 0):
                k.append([i-1,j])
            if(0 <= j+1 < m and maze[i][j+1] == 0 and points[i][j+1] == 0):
                k.append([i,j+1])
            if(0 <= j-1 < m and maze[i][j-1] == 0 and points[i][j-1] == 0):
                k.append([i,j-1])
        #     print('test4',k)
            return k

        def get_path(i,j,maze,path,points):
            global res
            k = get_points(i,j,maze,points)
            points[i][j] = 1
        #     print('test2',k)
            if(len(k) > 0):
                for num1 in range(len(k)):
                    if(num1 == 0):
                        path.append(k[num1])
                    else:
                        path[-1] = k[num1]
                    if(k[num1] == [n - 1,m - 1]):
                        if(len(res) == 0 or len(path) < len(res)):
                            res = path
                    else:
                        tpath = path.copy()
                        tpoints = points.copy()
        #                 print('test1',tpath,tpoints)
                        get_path(k[num1][0],k[num1][1],maze,tpath,tpoints)

        global res
        res = []

        get_path(0,0,maze,path,points)

        print('(0,0)')
        for num2 in range(len(res)):
            print('(%d,%d)'%(res[num2][0],res[num2][1]))
    except:
        break
参考1
"""
为何是真正?因为看了下别人的python 解法,都有个弊端,就是只能做从起点0到终点的唯一路径的题,如果出现分支,
或者多路径求最短那么那些方法就不适用了。相对而言,以下做法不仅可以实现多路径下的最短到终点探索,
还能实现任意两点之间的最短路径返回,而且代码还不长,符合python人生苦短特点,所以成为真!到最后面附原试题:
python是解简单题最好用的方法
"""

#利用动态规划和递归解
def jud(x,y,l,ll,lll):#求x,y点坐标在迷宫里的可能走法,即向上,向下,向左,向右
    n,m=len(l)-1,len(l[0])-1 #l为迷宫位置二维图,ll为迷宫的每点从起点到该点
    k=[]     #的最短路径,lll为记录正在探索的从起点到该点的路线用以避免走重复
    if x+1<=n and (x+1,y) not in lll and l[x+1][y]!=1:k+=[(x+1,y)]
    if x-1>=0 and (x-1,y) not in lll and l[x-1][y]!=1:k+=[(x-1,y)]
    if y+1<=m and (x,y+1) not in lll and l[x][y+1]!=1:k+=[(x,y+1)]
    if y-1>=0 and (x,y-1) not in lll and l[x][y]!=1:k+=[(x,y-1)]
    return k
def mg(x,y,l,ll,lll):#x,y为该点坐标,其余同上,探索x,y的走法
    k=jud(x,y,l,ll,lll)#k为可能的走法
    lll+=[(x,y)]        #lll位置储存
    if len(k)>0:        #是否为可走
        for v in k:
            x1,y1=v
            if not ll[x1][y1] :  #如果x1,y1位置 还没有路径信息,用x,y位置进
                ll[x1][y1]=ll[x][y]+[(x1,y1)] #行更新
            if len(ll[x1][y1])>=len(ll[x][y])+1: #如果x1,y1之前储存的路径#要长于从x,y的路径到x1,y1的,则更新x1,y1路径信息
                ll[x1][y1]=ll[x][y]+[(x1,y1)]
            mg(x1,y1,l,ll,lll.copy())  #再对x1,y1 这点进行探索
    return False

while True:
    try:
        nn,mm=list(map(int,input().split()))
        l,ll,lll=[],[],[]
        for i in range(nn):
            l+=[list(map(int,input().split()))]
        for i in range(nn):
            ll.append([])
            for j in range(mm):
                ll[i].append([])
        ll[0][0]=[(0,0)]
        mg(0,0,l,ll,lll)   # 设置起始点为(0,0),你也可以设为其他点为起始,
        for v in ll[-1][-1]: #来探索其他点到任意一点的最短位置
            print("(%d,%d)"%(v[0],v[1])) #ll[-1][-1], 指的是将右下角一点设
    except:
        break
#为终点并打印出来,你也可以求其他点,如ll[2][3],来实现任意
#两点求最短路

"""
题目描述
定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
int maze[5][5] = {
    0, 1, 0, 0, 0,


    0, 1, 0, 1, 0,


    0, 0, 0, 0, 0,


    0, 1, 1, 1, 0,


    0, 0, 0, 1, 0,
}

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。

Input

一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0

Sample Output

(0, 0)

(1, 0)

(2, 0)

(2, 1)

(2, 2)

(2, 3)

(2, 4)

(3, 4)

(4, 4)

输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:
左上角到右下角的最短路径,格式如样例所示。

示例1
输入
复制
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出
复制
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)斜体内容
"""
参考2
输入:
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0 
0 1 1 1 0
0 0 0 1 0
输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
输入和输出

 

 

def strBeauty(s):
    beauty = 0
    dict1 = {}
    # 字典放名字中每种字母对应出现到次数
    for a in set(s):
        k = s.count(a)
        dict1[a] = k
    # print(dict1)

    # 每种字母的出现次数从大到小排列
    time_list = sorted(dict1.values(), reverse=True)
    # print(time_list)

    # 次数从大到小以此乘以26,25,24...
    for i in range(len(time_list)):
        beauty += (26 - i) * time_list[i]
    return beauty


while True:
    try:
        n = int(input())
        sa, sb = input(), input()
        print(strBeauty(sa))
        print(strBeauty(sb))
    except:
        break
me1函数
while True:
    try:

        n = int(input())
        sa,sb = input(),input()
        dict1,dict2 ={},{}
        beauty1 = 0
        beauty2 = 0
        #######################################
        # 字典放名字中每种字母对应出现到次数
        for a in set(sa):
            k1 = sa.count(a)
            dict1[a] = k1
        # print(dict1)

        # 每种字母的出现次数从大到小排列
        time_list1 = sorted(dict1.values(),reverse=True)
        # print(time_list1)

        # 次数从大到小以此乘以26,25,24...
        for i in range(len(time_list1)):
            beauty1 += (26-i) * time_list1[i]
        print(beauty1)

        #######################################
        # 字典放名字中每种字母对应出现到次数
        for b in set(sb):
            k2 = sb.count(b)
            dict2[b] = k2
        # print(dict2)

        # 每种字母的出现次数从大到小排列
        time_list2 = sorted(dict2.values(),reverse=True)
        # print(time_list2)

        # 次数从大到小以此乘以26,25,24...
        for j in range(len(time_list2)):
            beauty2 += (26-j) * time_list2[j]
        print(beauty2)

    except:
        break
me2
# while True:
#     try:
#         #获取输入的单词数量
#         N = int(input())
#         while N:
#             #获取输入的单词
#             data = input()
#             #去重存入字典
#             d = {}
#             # 没有使用count的方式,就只能用这个了
#             for word in data:
#                 if word not in d:
#                     d[word] = 1
#                 else:
#                     d[word] = d[word] + 1
#
#             d1 = sorted(d.values() ,reverse=True)
#             ans = 0
#             m = 0
#             for word in d1:
#                 ans = ans + (26-m)*word
#                 m = m + 1
#             print(ans)
#             N = N - 1
#     except:
#         break
########################################################
while 1:
    try:
        n = int(input())
        l = []
        nums = []
        values = list(reversed(range(1,27)))
        for i in range(n):
            l.append(input())
            char = []
            nums = []
            for j in range(len(l[i])):
                if l[i][j] not in char:
                    char.append(l[i][j])
                    nums.append(1)
                else:
                    nums[char.index(l[i][j])] += 1
            new_word = ''
            for k in range(len(char)):
                new_word += char[nums.index(max(nums))]
                nums[nums.index(max(nums))] = 0
            key_values = {}
            score = 0
            for a in range(len(new_word)):
                key_values[new_word[a]] = values[a]
            for j in l[i]:
                score += key_values[j]
            print(score)
    except:
        break
参考1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2022-04-19 22:15  pf42280  阅读(58)  评论(0)    收藏  举报