Three Kingdoms(优先队列+bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=3442

题意:ABCD有各自的攻击力与攻击范围,刘备只能走"C"与".",问刘备从"s" 走到"!"受到的最小攻击力。ps(受过一次攻击的下次将不会再对刘备造成伤害)

思路:用优先队列,每次搜索攻击力最小的,并对当前的状态标记。。。

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <queue>
#include <stdlib.h>
using namespace std;
const int N=60;
char Map[N][N];
int a[N][N][6],vis[N][N][35];
int dir[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
int n,m,sx,sy,ex,ey;
struct node
{
    int x,y,hp,state;
    friend bool operator < (node a,node b)
    {
        return b.hp < a.hp;//在这跪了n遍。。要想优先队列里的值从小到大排列,则比较函数应该从大到小排
    }
};
bool in(int x,int y)
{
    if (x >= 1&&x <= n&&y >= 1&&y <= m)
        return true;
    return false;
}
bool judge(int x1,int y1,int x2,int y2,int c)
{
    if(abs(x1-x2)+abs(y1-y2) <= c)
        return true;
    return false;
}

void deal(int x,int y,char ch)
{
    if (ch=='A')
    {
        for (int i = x-2; i <= x+2; i++)
        {
            for (int j = y-2; j <= y+2; j++)
            {
                if(in(i,j)&&judge(x,y,i,j,2))
                    a[i][j][0] = 1;
            }
        }
    }
    else if (ch=='B')
    {
        for (int i = x-3; i <= x+3; i++)
        {
            for (int j = y-3; j <= y+3; j++)
            {
                if (in(i,j)&&judge(x,y,i,j,3))
                    a[i][j][1] = 2;
            }
        }
    }
    else if (ch=='C')
        a[x][y][2] = 3;
    else if (ch=='D')
    {
        for (int i = x-2; i <= x+2; i++)
        {
            for (int j = y-2; j <= y+2; j++)
            {
                if (in(i,j)&&judge(x,y,i,j,2))
                    a[i][j][3] = 4;
            }
        }
    }
    else if (ch=='E')
    {
        for (int i = x-1; i <= x+1; i ++)
        {
            for (int j = y-1; j <= y+1; j ++)
            {
                if (in(i,j)&&judge(x,y,i,j,1))
                    a[i][j][4] = 5;
            }
        }
    }
}
int bfs()
{
    priority_queue<node>q;
    while(!q.empty()) q.pop();
    q.push((struct node)
    {
        sx,sy,0,0
    });
    vis[sx][sy][0] = 1;
    while(!q.empty())
    {
        node temp,t = q.top();
        q.pop();
        printf("%d %d %d
",t.x,t.y,t.hp);
        if (t.x==ex&&t.y==ey)
            return t.hp;
        for (int i = 0; i < 4; i++)
        {
            temp.x = t.x+dir[i][0];
            temp.y = t.y+dir[i][1];
            temp.hp = t.hp;
            temp.state = t.state;
            if (in(temp.x,temp.y)&&(Map[temp.x][temp.y]=='C'||Map[temp.x][temp.y]=='$'||Map[temp.x][temp.y]=='.'||Map[temp.x][temp.y]=='!'))
            {
                for (int k = 0; k < 5; k++)
                {
                    if((temp.state&(1<<k))==0&&a[temp.x][temp.y][k])
                    {
                        temp.hp+=a[temp.x][temp.y][k];
                        temp.state+=(1<<k);
                    }
                }
                if (!vis[temp.x][temp.y][temp.state])
                {
                    vis[temp.x][temp.y][temp.state] = 1;
                    q.push(temp);
                }
            }
        }
    }
    return -1;
}
int main()
{
    int t,o = 0;
    cin>>t;
    while((t--))
    {
        o++;
        cin>>n>>m;
        memset(a,0,sizeof(a));
        memset(vis,0,sizeof(vis));
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cin>>Map[i][j];
                if (Map[i][j]=='A'||Map[i][j]=='B'||Map[i][j]=='C'||Map[i][j]=='D'||Map[i][j]=='E')
                    deal(i,j,Map[i][j]);
                if (Map[i][j]=='$')
                {
                    sx = i;
                    sy = j;
                }
                if (Map[i][j]=='!')
                {
                    ex = i;
                    ey = j;
                }
            }
        }
        int ans = bfs();
        printf("Case %d: %d
",o,ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lahblogs/p/3618230.html