【洛谷】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;
}

  

posted @ 2017-12-08 21:28  surpassion  阅读(311)  评论(0编辑  收藏  举报