【洛谷】Magicite
自己出的一道题~
题目描述
srf最近喜欢颓废,他最喜欢玩的游戏是Magicite,以至于有一天srf在睡梦中变成了一个连斧头都没有的角色(so他除了跑,什么都做不了),幸好由于srf平日里玩得不错,他成为了里面攻击力最高的角色——法师(然而srf连个魔杖都没有,so你懂得,他打不了怪),but他有一个法师的技能——瞬移。在n*m的地图中,“.”表示空地,srf可以待在那里,“#”表示有怪兽,srf显然不能待在那里。Srf每次可以向上下左右四个方向中的某一个移动一个单位,作为一个法师,srf总共有p点魔力值,他使用MAGIC的话,每次可以移动q个单位,每次消耗k点魔力值(k<=p)。每次普通移动都可以回复1点魔力值。现在,srf在左上角,关卡终点在右下角。(移动规定:每次都必须移动到“.”空地。)
Srf想问你,到终点最少要几步?
当然,也许srf一定不能过关,此时请输出-1.
输入输出格式
输入格式:
第一行分别是n,m,p,k,q,意思如题目描述所示。
接下来是一个n*m的矩阵,描述这个地图。
输出格式:
一个整数,表示最少要花费的时间。
或-1.
输入输出样例
输入样例#1:
3 4 10 4 2
..##
#.##
....
输出样例#1:
3
说明
1<=n,m,q<=1000,k<=p<=60
标程
#include<bits/stdc++.h> using namespace std; const int dx[4] = {-1,0,1,0} , dy[4] = {0,1,0,-1}; int front,rear,n,m,p,q,k,x[1000005],y[1000005],dep[1000005],Map[1005][1005],ans[1005][1005][61],ma[1000005]; string st; int main() { scanf("%d %d %d %d %d",&n,&m,&p,&k,&q); int rx[4] = {-q,0,q,0} , ry[4] = {0,q,0,-q}; for (int i = 1 ; i <= n ; i ++) { cin>>st; for (int j = 1 ; j <= m ; j ++) { Map[i][j] = (st[j-1] == '#') ? 0 : 1; for (int t = 0 ; t <= p ; t ++) ans[i][j][t] = INT_MAX; } } for (int i = 0 ; i <= p ; i ++) ans[1][1][i] = 0; x[1] = 1; y[1] = 1; dep[1] = 0; front = 1 ; rear = 1; ma[1] = p; while (front <= rear) { int nx = x[front] , ny = y[front] , nd = dep[front] , nm = ma[front] , next_ma = (nm + 1 > p) ? nm : nm + 1; for (int i = 0 ; i < 4 ; i ++) { int tx = nx + dx[i] , ty = ny + dy[i]; if (tx > 0 && tx <= n && ty > 0 && ty <= m && nd + 1 < ans[tx][ty][next_ma]) { rear ++; x[rear] = tx; y[rear] = ty; dep[rear] = nd + 1; ma[rear] = next_ma; ans[tx][ty][next_ma] = nd + 1; } } if (nm >= k) { for (int i = 0 ; i < 4 ; i ++) { int tx = nx + rx[i] , ty = ny + ry[i]; if (tx > 0 && tx <= n && ty > 0 && ty <= m && nd+1 < ans[tx][ty][nm-k]) { rear ++; x[rear] = tx; y[rear] = ty; dep[rear] = nd + 1 ; ma[rear] = nm-k; ans[tx][ty][nm-k] = nd + 1; } } } front++; } int Min = INT_MAX; for (int i = 0 ; i <= p ; i ++) if (ans[n][m][i] < Min) Min = ans[n][m][i]; if (Min != INT_MAX) cout<<Min<<endl; else cout<<-1<<endl; return 0; }