Carrying Out A Task

题目描述

During the process of the military exercise, there is a ship on the sea level .The ship will go to certain place to carry out a task. For every action, the ship has two ways to sail. They are normal sailing and accelerated sailing. The normal speed of the ship is certain, when the ship sails normally, it can only move 1 step to the adjacent normal sea level. The ship can also accelerate. There are 2 kinds of accelerated sailings, one is moving forward d steps (d <= 5) in a straight line, and it must move forward d steps exactly every time it accelerates, The d steps must be on the normal sea level, otherwise, it can not accelerate. The other is accelerating while getting through the undercurrent. There are a lot of undercurrents on the sea, and entering the undercurrent area needs to accelerate when the ship is 1 step to the undercurrent. However, the ship itself will be damaged more or less by the undercurrent,  After entering the undercurrent, the speed of the ship will become normal immediately. Every time it accelerates, the ship has to consume a certain B energy, and when it starts up ,it carries certain B energy. 

While the ship is sailing on the sea, it needs to consume a certain A energy. One unit of distance will consume one unit of A energy, and when the ship starts up, it carries enough A energy. 

There are many reefs on the sea, and the ship can not get through.

Now the ship is required to sail to the certain place, of course, to minimize the damage to the ship itself is a priority because the cost of ships is very expensive. The damage is, of course, the smaller, the better. At the same time, an attempt should be made to control the consumption of A energy to the smallest amount during the whole process because the cost of A energy is much more expensive than that of B energy, and you can use B energy which the ship carried when it started up as you wish.  

Now the question is to work out the minimal times of action from the departure point to the destination under the condition that to minimize the damage to the ship is a priority and then the consumption of A energy to the smallest degree. 

 

输入

The input file contains several test cases, the first line contains an integer T, indicates the number of test cases. In each case the first line includes two integers n, m (5 <= n, m <= 20), which indicate the size of the sea level for military exercises, and n rows and m columns are the current state of the sea level ('S' indicates the ship's initial position, 'E' indicates the destination place, '#' indicates the reefs, '*' indicates the undercurrent , ' ' the normal sea level), followed a line with a number d in it, it indicates the distance of the first kind of acceleration, then another line includes two integers, indicate that the initial value of the B energy and the value of the B energy needed while accelerating every time. 

 

输出

Output an integer to indicate the smallest times of action, and if can not reach the task place, then output "can not reach!" 

 

样例输入

复制样例数据

2
5 10
##########
#E       #
#*###### #
#S       #
##########
5
10 2
6 10
##########
#E       #
#*######*#
#*######*#
#S       #
##########
5
3 2

样例输出

8
can not reach!

 

杭电2453

n*m的迷宫

起点S,终点E。#为障碍,*为漩涡,空格为正常路径。

携带无限A类油,X升B类油,一次我可以走一格,或者选择加速。走一格消耗一升A,一次加速多消耗Y升B。

存在连续的长为d的空格时,可以加速,漩涡可以走,进入漩涡前必须加速,且加速效果仅保证能出漩涡。

优先级:经过漩涡少〉消耗A类油少〉进行的决策少(走一格或者加速)

 

参考:https://blog.csdn.net/zhuhuangjian/article/details/12402323

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

struct node{
    int x,y,res,da,op,A,j;//res,剩余B类油;da经过的漩涡;A消耗A类油;j走过的回合数
};
bool operator < (node x,node y){//用于判定优先级
    if(x.da==y.da){
        if(x.A==y.A){
            return x.op>y.op;
        }
        return x.A>y.A;
    }
    return x.da>y.da;
}
int dx[]={-1,0,0,1};//用于广搜
int dy[]={0,1,-1,0};
int n,m,d,e,c;
char mp[25][25];//地图
int da[25][25],A[25][25],jia[25][25];

void init(){//初始化
    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j){
            da[i][j]=A[i][j]=jia[i][j]=410;
        }
    }
}

void bfs(node vs,node ve){
    int flag=-1;
    init();
    priority_queue<node> q;
    node vn,vw;
    da[vs.x][vs.y]=A[vs.x][vs.y]=jia[vs.x][vs.y]=0;
    vn.x=vs.x;
    vn.y=vs.y;
    vn.res=e;
    vn.da=0;
    vn.A=0;
    vn.op=0;
    q.push(vn);
    while(!q.empty()){
        vn=q.top();
        q.pop();
        if(vn.x==ve.x&&vn.y==ve.y){//到达终点
            flag=vn.op;
            break;
        }

        for(int i=0;i<4;++i){//广搜
            int nx,ny;
            if(vn.res>=c){//可以加速的话
                nx=vn.x;
                ny=vn.y;
                int blag=1;
                for(int j=0;j<d;++j){//判断第一类加速
                        nx+=dx[i];
                        ny+=dy[i];
                        if(nx<0||nx>=n||ny<0||ny>=m){
                            blag=0;
                            break;
                        }
                        if(mp[nx][ny]!=' '&&mp[nx][ny]!='E'){
                            blag=0;
                            break;
                        }
                }
                if(blag){//可以进行第一类加速
                    if((da[nx][ny]>vn.da)||(da[nx][ny]==vn.da&&A[nx][ny]>vn.A+d)||(da[nx][ny]==vn.da&&A[nx][ny]==vn.A+d&&jia[nx][ny]>vn.j+1)){//三类优先级判断
                        da[nx][ny]=vn.da;
                        A[nx][ny]=vn.A+d;
                        jia[nx][ny]=vn.j+1;

                        vw.x=nx;
                        vw.y=ny;
                        vw.res=vn.res-c;
                        vw.da=vn.da;
                        vw.op=vn.op+1;
                        vw.A=vn.A+d;
                        vw.j=vn.j+1;
                        q.push(vw);
                    }
                }
            }
            //不能进行第一类加速
            nx=vn.x+dx[i];
            ny=vn.y+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&mp[nx][ny]!='#'){//障碍不能走
                if(mp[nx][ny]!='*'&&((da[nx][ny]>vn.da)||(da[nx][ny]==vn.da&&A[nx][ny]>vn.A+1)||(da[nx][ny]==vn.da&&A[nx][ny]==vn.A+1&&jia[nx][ny]>vn.j))){//正常行驶
                    da[nx][ny]=vn.da;
                    A[nx][ny]=vn.A+1;
                    jia[nx][ny]=vn.j;

                    vw.x=nx;
                    vw.y=ny;
                    vw.res=vn.res;
                    vw.da=vn.da;
                    vw.op=vn.op+1;
                    vw.A=vn.A+1;
                    vw.j=vn.j;
                    q.push(vw);
                }
                else if(mp[nx][ny]=='*'&&vn.res>=c&&((da[nx][ny]>vn.da)||(da[nx][ny]==vn.da&&A[nx][ny]>vn.A+1)||(da[nx][ny]==vn.da&&A[nx][ny]==vn.A+1&&jia[nx][ny]>vn.j+1))){//需要经过漩涡,必须加速进入
                    da[nx][ny]=vn.da+1;
                    A[nx][ny]=vn.A+1;
                    jia[nx][ny]=vn.j+1;

                    vw.x=nx;
                    vw.y=ny;
                    vw.res=vn.res-c;
                    vw.da=vn.da+1;
                    vw.op=vn.op+1;
                    vw.A=vn.A+1;
                    vw.j=vn.j+1;
                    q.push(vw);
                }
            }
        }
    }
    if(flag==-1){//无法到达终点,flag值为-1
        printf("can not reach!\n");
    }
    else{
        printf("%d\n",flag);
    }
}
int main()
{
    int T;
    scanf("%d",&T);//多组数据
    while(T--){
        scanf("%d %d",&n,&m);
        getchar();
        for(int i=0;i<n;++i){
            gets(mp[i]);
        }
        scanf("%d %d %d",&d,&e,&c);//d,第一类加速距离,e初始B类油量,c,加速消耗b类油量
        node vs,ve;//记录起点和终点
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(mp[i][j]=='S'){
                    vs.x=i;
                    vs.y=j;
                }
                else if(mp[i][j]=='E'){
                    ve.x=i;
                    ve.y=j;
                }
            }
        }
        bfs(vs,ve);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值