死亡迷宮

[quote]
背景

很久以前,迷宮裏住着一個惡魔。一天,我們偉大的英雄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

[/quote]

思路:
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章