引用
背景
很久以前,迷宫里住着一个恶魔。一天,我们伟大的英雄Jacky无意中踏入了这个迷宫。不幸的是,他被困在这个迷
宫当中了。恶魔在迷宫中召唤出了许多怪物,想要阻止Jacky逃脱。在迷宫中,Jacky遇到一个一位巫师。他给了
Jacky迷宫的地图,并告诉他迷宫的入口很快会关闭。Jacky必须以非常快的速度到达入口,并且有足够的力气推开挡
在入口的岩石。于是,Jacky带着地图一路向着出口走去……
问题
给出Jacky和各怪物的能量, 攻击力, 防御力,和迷宫的地图,请你计算一下 能量/耗时 的最大值。
当Jacky走到有怪物的地方时,Jacky会先进行攻击,然后怪物攻击,然后Jacky……当一方的能量小于等于0时攻击停止
,并且小于等于0的一方死亡。攻击时,每次对方损耗的能量为己方的攻击力减去对方的防御力。
当Jacky走到标有‘A’,‘B’,‘C’的地方时,Jacky的相应属性会得到增加。
对应关系如下:
[A] 能量 + P
[B] 攻击力 + Q
[C] 防御力 + R
如果耗时超过100,那么门将永远也打不开了,我们的Jacky也就永远的困在了这个暗无天日的迷宫之中……
输入
标准输入包含多组数据。
每组数据的第一行有六个整数W (1 <= W <= 20), H (1 <= H <= 20), P (1 <= P <= 10), Q (1<= Q <= 10), R (1
<= R <= 10), M (0 <= M <= 5). 迷宫是由一个W*H的矩形区域构成。M表示怪物的数量。
Jacky每个单位时间可以移动到相邻的4个格中,当然,必须得保证目标格在矩形区域中。默认的起始时间是0。
与怪物战斗不会花费额外的时间。
其后H行每行严格包含W个字符。用如下的各字符表示这个迷宫的地图:
[#]表示一堵墙(Jacky是不会穿墙术的)
[.] Marks an empty space, into which you can move.表示一块空地。
[S]表示Jacky的初始位置。
[E]表示迷宫的入口。
[0]数字表示各怪物的标号。
[A]表示属性增加地点。(使用次数仅限于一次)
其后一行有三个整数,表示Jacky的能量,攻击力,和防御力。
其后M行,每行有四个整数,表示怪物的编号,和这个怪物的各属性。
输出
对于每组输入数据,输出 能量/耗时 的最大值,并保留4位小数。如果Jacky不能到达出口,输出“impossible”。数
据之间无空行。
样例输入
6 17 7 5 4 3
#################
##E......#......#
#A#....#.0.##.#B#
#1###########2###
#.S............C#
#################
100 59 10
0 23 48 0
1 65 41 0
2 20 27 0
样例输出
3.7037
思路:
1:不是寻找最佳路径,只是模拟寻找路径过程。
2:杀死的怪物不能重生
3:简单起见,输入和输出没有按题目的要求。 输出的是Jacky探寻的路径和出来后的属性
########################################### $MAZE_DATA = Array.[](['#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'], ['#','#','E','.','.','.','.','.','.','#','.','.','.','.','.','.','#'], ['#','A','#','.','.','.','.','#','.','0','.','#','#','.','#','B','#'], ['#','1','#','#','#','#','#','#','#','#','#','#','#','2','#','#','#'], ['#','.','S','.','.','.','.','.','.','.','.','.','.','.','.','C','#'], ['#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#']) $MAZE_DATA_WIDTH = 17 $MAZE_DATA_HEIGHT = 6 $FACTOR_P = 7 $FACTOR_Q = 5 $FACTOR_R = 4 $FACTOR_M = 3 $JACKY_DATA = Array.[](100,59,10) $OGRE_DATA = Array.[]([23,48,0],[65,41,0],[20,27,0]) $TOTAL_TIME_LIMIT = 100 $TIME_UNIT = 4 ########################################## $GRID_WALL = '#' $GRID_EMPTY = '.' $GRID_START = 'S' $GRID_END = 'E' $GRID_ATTRIBUTE = /[A-Z]/ $GRID_OGER = /\d/ $GRID_PASS = '~' ########################################### $ALL_PATHES = Array.[]() $HAVE_OUT = false ########################################### def walkToGrid(x,y,pathStack,detectedGrids) grid = gridData(x,y) return false if !grid || grid == $GRID_WALL || hasWalkTo(x,y,detectedGrids) #p "Walk to "+x.to_s+","+y.to_s+" " detectedGrids.push([x,y]) pathStack.push([x,y]) if !notWays(x,y,detectedGrids) if grid == $GRID_END pathStack.push([x,y]) isOK = true elsif grid =~ $GRID_ATTRIBUTE #meet something to eat ,become more strong p "Meet something to eat " $JACKY_DATA[0] += $FACTOR_P $JACKY_DATA[1] += $FACTOR_Q $JACKY_DATA[2] += $FACTOR_R setGridData(x,y,$GRID_EMPTY) elsif grid =~ $GRID_OGER # meet oger and fright ogerIndex = grid.to_i while true $OGRE_DATA[ogerIndex][0] -= $JACKY_DATA[1]-$OGRE_DATA[ogerIndex][2]#jacky attack first break if $OGRE_DATA[ogerIndex][0]<=0 $JACKY_DATA[0] -= $OGRE_DATA[ogerIndex][1] - $JACKY_DATA[2]#oger attack break if $JACKY_DATA[0]<=0 end if $JACKY_DATA[0]<=0 p "Jacky Dead !" exit else p "Jacky kill oger [" + grid +"]" setGridData(x,y,$GRID_EMPTY) # clear the oger end end if !isOK checkPreStep(pathStack,detectedGrids) #check time if detectedGrids.size/$TIME_UNIT >= $TOTAL_TIME_LIMIT p detectedGrids p "Out of Time,man !" exit end else tmp = pathStack.clone #save the success case to cache $ALL_PATHES << tmp p "Find the outlet" $HAVE_OUT = true return true end # The walking strategy is very important, but in here jacky could not to pick the best way because he doesn't know how to choice walkToGrid(x+1,y,pathStack,detectedGrids) if !$HAVE_OUT walkToGrid(x-1,y,pathStack,detectedGrids) if !$HAVE_OUT walkToGrid(x,y+1,pathStack,detectedGrids) if !$HAVE_OUT walkToGrid(x,y-1,pathStack,detectedGrids) if !$HAVE_OUT end def gridData(x,y) return nil if !validateXY(x,y) return $MAZE_DATA[y][x] end def setGridData(x,y,data) $MAZE_DATA[y][x]=data end def validateXY(x,y) return (x < $MAZE_DATA_WIDTH) && (x>=0) && (y<$MAZE_DATA_HEIGHT) && (y >=0) end # whether this position has any pathes to walk along def notWays(x,y,detectedGrids) nextXGrid = gridData(x+1,y) preXGrid = gridData(x-1,y) nextYGrid = gridData(x,y+1) preYGrid = gridData(x,y-1) if !nextXGrid&&!preXGrid&&!nextYGrid&&!preYGrid return true end return (nextXGrid==$GRID_WALL || ((hasWalkTo(x+1,y,detectedGrids))&&!hasSuccesPathToGrid(x+1,y)))&&(preXGrid==$GRID_WALL || ((hasWalkTo(x-1,y,detectedGrids))&&!hasSuccesPathToGrid(x-1,y)))&&(nextYGrid==$GRID_WALL || (hasWalkTo(x,y+1,detectedGrids)&&!hasSuccesPathToGrid(x,y+1)))&&(preYGrid==$GRID_WALL || ((hasWalkTo(x,y-1,detectedGrids))&&!hasSuccesPathToGrid(x,y-1))) end def hasSuccesPathToGrid(x,y) $ALL_PATHES.each{|path| path.each{ |grid| return true if grid[0]==x && grid[1]==y } } return false end def hasWalkTo(x,y,detectedGrids) return false if !validateXY(x,y) detectedGrids.each{|grid| return true if grid[0]==x && grid[1] ==y } return false; end #check whether previous step is effective def checkPreStep(pathStack,detectedGrids) return if pathStack.size<1 ok = false while !ok preStep = pathStack.at(pathStack.size-1) if notWays(preStep[0],preStep[1],detectedGrids) detectedGrids << pathStack.pop else ok=true end end preStep = pathStack.at(pathStack.size-1) lastDetectedGrid = detectedGrids.at(detectedGrids.size-1) detectedGrids.push(preStep) if (lastDetectedGrid[0] != preStep[0] || lastDetectedGrid[1]!=preStep[1]) end #get the start position and the end position y=0 $MAZE_DATA.each{|y_data| x=0 y_data.each{|x_data| if x_data==$GRID_START $START_X = x $START_Y = y elsif x_data==$GRID_END $END_X = x $END_Y = y end x += 1 } break if $START_X&&$START_Y&&$END_X&&$END_Y y += 1 } $detectedGrids = Array.new walkToGrid($START_X,$START_Y,Array.[](),$detectedGrids) p "----------- Walking Track-------------------" p $detectedGrids p $JACKY_DATA