腾讯马拉松之海岛小Q

Q漂流到了一座海岛上。这座海岛可以看作是一个矩形,划分为N*M个小格子,每个格子用(x,y)来表示,对应的海拔高度为h(x,y)。此外,海水会随着时间涨潮落潮,从海拔高度0涨到H,再落潮,高度回落至0,如此反复。当某个点的海拔高度小于潮水时,会从陆地变成海洋(不考虑该点是否被其他陆地包围),反之也会由海洋变为陆地。

现在,小Q想要从海岛上的A地走到B地。走的时候只能从当前格子走到其相邻(上下左右)四个格子之一,且花费一定的体力x

1.步行(从陆地到陆地):x为两块陆地的高度差dH加上固定消耗F

2.游泳(从海洋到海洋):x为固定的S

3.上岸或下水(从海洋或陆地到另一种地形):x为陆地高出海水的差dH加上固定消耗 F

Q可以在原地等待潮水涨落到0H之间的任意高度并随着潮水涨落,而无需消耗体力。为了简单起见,假定小Q每次移动可以在一瞬间完成,以至于在移动的过程中海水不会涨落。现在,给定一个起点和一个终点,不限小Q的移动时间,请求出小QAB需要的最少体力。


输入:

输入包含多组数据,直到文件结束。对于每一组数据,第一行给出5个整数 N, M, H, S, FNM分别是海岛的长和宽,H是潮水的最大高度,S是小Q游泳到相邻点花费的体力。是步行、上岸、以及下水的固定消耗体力部分。

接下来一行是4个正整数sx,sy,tx,ty,(1< sxtx="N1< syty="M)。(sx,sy)是小Q的起点,(tx,ty)是小Q的终点。接下来N行,每行M个数,用来描述每个点的海拔高度。

每一个输入的数字都是整数,其中2< NM="1002< FS="1000< H hxy="1000


输出:

对于每组数据输出一行,输出小Q从起点到终点所需要的最小体力。



样例输入:

3 5 6 3 1

1 1 3 3

5 6 7 8 9

5 6 7 8 9

5 6 7 8 9

3 5 5 3 1

1 1 3 3

5 6 7 8 9

5 6 7 8 9

5 6 7 8 9

3 5 20 3 2

1 1 3 5

10 10 3 10 10

10 10 3 10 10

10 10 3 10 10


样例输出:

5

6

12


# -*- encoding:UTF-8 -*-
data_file=open("c:/data.txt",'r')
N,M,H,S,F=[int(i) for i in data_file.readline().strip('\n').split(' ')]
print N,M,H,S,F
island=[]
paths=[]
#都读一组数据
def read_file():
    l =data_file.readline()
    if len(l) >=4:
        x1,y1,x2,y2=[int(i) for i in l.strip('\n').split(' ')]
        
        for i in range(int(N)):
            island.append([int(i) for i in data_file.readline().strip('\n').split(' ')])
        return x1,y1,x2,y2
    return (-1,-1,-1,-1)
    
    

#x,y的高度
def h(x,y):
    return island[x-1][y-1]

#找到岛上的最高点
def highest(island):
    h_max = 0
    for i in island:
        for j in i:
            if j > h_max:
                h_max = j
                
#输出从()到()的所有路径
def pailie(x0,y0,x,y,res=[]):
    res.append((x0,y0))
    if x0 == x and y0 == y:
        paths.append(res)
        return
    if x0 < x and y0 < y:
        pailie(x0+1,y0,x,y,res[:])
        pailie(x0,y0+1,x,y,res[:])
    if x0 ==x and y0 < y:
        pailie(x0,y0+1,x,y,res)
    if x0 < x and y0 == y:
        pailie(x0+1,y0,x,y,res)

#计算每条路径的能力消耗    
def cal_each_path(l):
    cost=0
    for i in range(len(l)-1):
        x0,y0=l[i]
        x1,y1=l[i+1]
        high_distance=abs(h(x0,y0)-h(x1,y1))
        cost += high + F
    return cost

def chose_one_path(path):
    least_digest=9999
    for i in path:
        eng = cal_each_path(i)
        if eng < least_digest:
            least_digest = eng
    return least_digest

#根据所给出的能量消耗,walk,swim等,作出选择,输出        
def chose(x1,y1,x2,y2):
    start = h(x1,y1)
    end = h(x2,y2)
    #走路的消耗
    walk_exp = chose_one_path(paths)
    swim_exp = 0
    if H >= start and H >= end:
        swim_exp = S
    if start > H and end < H:
        swim_exp = start - H + F + S
    if end > H and start < H:
        swim_exp = end - H + F + S
    if start > H and end > H:
        swim_exp = start - H + end - H + F + F + S
    
    if walk_exp < swim_exp:
        print walk_exp
    else:
        print swim_exp
        
def run():
    while(data_file):        
        x1,y1,x2,y2 = read_file()

        if x1 == -1:
            return
        else:
            print x1,y1,x2,y2
            for i in island:
                print i
            
            chose(x1,y1,x2,y2)
            
            while len(island)>0:
                island.pop()

if __name__ == "__main__":
    run()


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值