hdu 2453

题目

在一个n*m的海域里,B类油有限的情况下,从起点到终点的最少操作数(船的损坏最小,其次A类油用的尽量少)

‘#’不能走,其他时候有两种操作方式:1.在空白海域,一次走一格,2.在有一条长度>=d的连续空白海域,可以在消耗B类油的情况下,一次走d格,在暗流中,必须使用这种方式,但一次只能运行一格。

然后是不管在何种海域,只要走一格就要消耗一单位的A;


优先队列广搜,优先级:选损坏最小的,如果损坏程度相同,就选A消耗最小的。

避免重复入队:开了三个标记数组,一个是在(x,y)处的损坏值,一个是A的消耗,一个是剩余的B(也就是看第二种运行方式的次数),显然在当前的状态下,如果(x,y)的损坏值可以变小,那这个状态就可以入队。如果损坏值相同,那就看A,其次看加速次数


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

struct node
{
    int x,y;
    int res;
    int da;
    int op;
    int A;
    int j;
};
bool operator < (node i,node j)
{
    if(i.da==j.da)
    {
        if(i.A==j.A) return i.op>j.op;
        return i.A>j.A;
    }
    return i.da>j.da;
}
int t,n,m,d,e,c;
char map[30][30];

int dx[]={-1,0,0,1};
int dy[]={0,1,-1,0};
int da[30][30],A[30][30],jia[30][30];
inline void bfs(node vs,node ve)
{
    int flag=-1;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) da[i][j]=jia[i][j]=A[i][j]=410;
    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.op=0,vn.A=0;
    q.push(vn);
    while(!q.empty())
    {
        vn=q.top();q.pop();
        // printf("%d %d %d\n",vn.x,vn.y,vn.res);
        if(vn.x==ve.x&&vn.y==ve.y)
        {
            flag=vn.op;
            break;
        }
        for(int i=0;i<4;i++)
        {
            int a,b;
            if(vn.res>=c)
            {
                a=vn.x,b=vn.y;
                int tag=1;
                for(int j=0;j<d;j++)
                {
                    a+=dx[i],b+=dy[i];
                    if(a<0||a>=n||b<0||b>=m) 
                    {
                        tag=0;break;
                    }
                    if(map[a][b]!=' '&&map[a][b]!='E') 
                    {
                        tag=0;break;
                    }
                }
                if(tag)
                {
                    if(da[a][b]>vn.da||(da[a][b]==vn.da&&A[a][b]>vn.A+d)||((da[a][b]==vn.da&&A[a][b]==vn.A+d&&jia[a][b]>vn.j+1)))
                    {
                        da[a][b]=vn.da;
                        A[a][b]=vn.A+d;
                        jia[a][b]=vn.j+1;
                        vw.x=a,vw.y=b;
                        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);
                    }
                }
            }

            a=vn.x+dx[i],b=vn.y+dy[i];
            if(a>=0&&a<n&&b>=0&&b<m&&map[a][b]!='#')
            {
                if(map[a][b]!='*'&&((da[a][b]>vn.da||(da[a][b]==vn.da&&A[a][b]>vn.A+1)||((da[a][b]==vn.da&&A[a][b]==vn.A+1&&jia[a][b]>vn.j)))))
                {
                    da[a][b]=vn.da;
                    A[a][b]=vn.A+1;
                    jia[a][b]=vn.j;
                    vw.x=a,vw.y=b;
                    vw.da=vn.da;
                    vw.res=vn.res;
                    vw.op=vn.op+1;
                    vw.j=vn.j;
                    vw.A=vn.A+1;
                    q.push(vw);
                }
                else if(map[a][b]=='*'&&vn.res>=c&&((da[a][b]>vn.da||(da[a][b]==vn.da&&A[a][b]>vn.A+1)||((da[a][b]==vn.da&&A[a][b]==vn.A+1&&jia[a][b]>vn.j+1)))))
                {
                    da[a][b]=vn.da+1;
                    A[a][b]=vn.A+1;
                    jia[a][b]=vn.j+1;
                    vw.x=a,vw.y=b;
                    vw.da=vn.da+1;
                    vw.res=vn.res-c;
                    vw.op=vn.op+1;
                    vw.A=vn.A+1;
                    vw.j=vn.j+1;
                    q.push(vw);
                }
            }
        }
    }
    if(flag==-1) printf("can not reach!\n");
    else printf("%d\n",flag);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        getchar();
        for(int i=0;i<n;i++) gets(map[i]);
        scanf("%d%d%d",&d,&e,&c);

        node vs,ve;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                if(map[i][j]=='S') vs.x=i,vs.y=j;
                else if(map[i][j]=='E') ve.x=i,ve.y=j;
            }
        //   printf("%d %d %d %d z\n",vs.x,vs.y,ve.x,ve.y);
        bfs(vs,ve);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值