HDU 3442 Three Kingdoms 优先队列(非状压做法)

阅读: 评论:0

HDU 3442 Three Kingdoms 优先队列(非状压做法)

HDU 3442 Three Kingdoms 优先队列(非状压做法)

题意:给出一个maze(某三国志类型游戏地图

$ 代表起点

!代表终点

.   代表路

#  代表墙

A,B,C,D,E分别代表不同的防御塔,其射程和攻击力各不相同。但其中只有C是可以走的。且每种防御塔只会造成一次伤害。

求最小伤害,到不了终点惯例输出-1

思路:先用bfs把地图染色,记住每个点都会收到什么伤害,这里用set实现。

再bfs寻路,每个点的所有状态用点集表示(set<set<int> >,set<int>是点集,就是一种状态,而set<set<int> >就是一点的状态集),在bfs时确定同一个点不会有重复的状态被压入队列。

又考虑到状态较多,可能会MLE,使用优先队列,略去多余的状态点。

非状压做法代码:

<span style="font-size:14px;">#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
using namespace std;
bool vis[60][60];
set <int> maze[60][60];
int dirx[]={0,-1,1,0};
int diry[]={-1,0,0,1};
set <int> em;
typedef struct Node{int x;int y;int sum;public:Node(int xx,int yy,int ss){x=xx;y=yy;sum=ss;}
}Node;
typedef struct node{int x;int y;set <int> s;int ans;bool operator < (const node &a)const{if(a.ans==ans){if(a.x==x)return a.y<y;return a.x<x;}return a.ans<ans;}public:node(int xx,int yy,set<int> ss,int a){x=xx;y=yy;s=ss;a=0;set<int>::iterator it;for(it=s.begin();it!&#d();it++)a+=*it;ans=a;}
}node;
const int INF=0x3f3f3f3f;
int n,m,stx,sty,enx,eny;
void bfs(int x,int y,int r,int d){//。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。bfs对图染色queue <Node> que;que.push(Node(x,y,r));bool tvis[60][60]={0};tvis[x][y]=1;while(!pty()){Node t=que.front();que.pop();if(t.sum<0)continue;else{maze[t.x][t.y].insert(d);//。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。一点上的初始状态(会被哪些塔攻击到)for(int i=0;i<4;i++){int xx=dirx[i]+t.x;int yy=diry[i]+t.y;if(tvis[xx][yy]||xx<0||xx>=n||yy<0||yy>=m)continue;que.push(Node(xx,yy,t.sum-1));tvis[xx][yy]=0;}}}return ;
}
int main()
{int T;scanf("%d",&T);getchar();em.clear();for(int ppp=1;ppp<=T;ppp++){scanf("%d %d",&n,&m);getchar();memset(vis,0,sizeof(vis));for(int i=0;i<60;i++)for(int j=0;j<60;j++)maze[i][j].clear();char x;int ans=INF;enx=INF;eny=INF;for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%c",&x);if(x=='A'){bfs(i,j,2,1);vis[i][j]=1;}else if(x=='B'){bfs(i,j,3,2);vis[i][j]=1;}else if(x=='C'){bfs(i,j,0,3);}else if(x=='D'){bfs(i,j,2,4);vis[i][j]=1;}else if(x=='E'){bfs(i,j,1,5);vis[i][j]=1;}else if(x=='$'){stx=i;sty=j;}else if(x=='!'){enx=i;eny=j;}else if(x=='#'){vis[i][j]=1;}}getchar();}priority_queue <node> que;que.push(node(stx,sty,em,0));set <set<int> > event[60][60];//。。。。。。。。。。。。。。。。。。。。。。。。。。。。地图上每点的状态集初始为空for(int i=0;i<n;i++){for(int j=0;j<m;j++){event[i][j].clear();}}event[stx][sty].insert(em);while(!pty()){node t&#p();que.pop();if(t.x==enx&&t.y==eny){ans=t.ans;break;}else{for(int i=0;i<4;i++){int xx=dirx[i]+t.x;int yy=diry[i]+t.y;if(xx<0||yy<0||xx>=n||yy>=m||vis[xx][yy]) continue;set <int> mix;set_union(t.s.begin(),d(),maze[xx][yy].begin(),maze[xx][yy].end(),inserter(mix,mix.begin()));if(event[xx][yy].find(mix)==event[xx][yy].end()){//。。。。。。。。。。。。。。。若新的状态在点上没有出现过,就入队que.push(node(xx,yy,mix,0));event[xx][yy].insert(mix);//。。。。。。。。。。。。。。。。。。。。。。。。更新点的状态集}}}}if(ans==INF)ans=-1;printf("Case %d: %dn",ppp,ans);}
}</span><span style="font-size:24px;">
</span>

Description

Three Kingdoms is a funny game. Often Liu Bei is weak and has to run away,so in the game Liu Bei has a skill called "Dunzou". This time you are playing the role of Liu Bei.As Cao Cao's power is so strong, there is nothing you can do but escaping. Please select an optimal path to achieve the purpose .
To simplify the problem, Liu Bei can only move in one of the four direction (up, down,right,left) each time. The map contains the following characters: 
‘A’ : Representative of watchtower, which has an attack range of 2(measured by Manhattan distance),and an attack damage of 1. 
‘B’ : Representative of Fort, which has an attack range of 3(measured by Manhattan distance),and an attack damage of 2. 
‘C’ : Representative of Flame, which has an attack damage of 3 to those who step onto it. 
‘D’ : Representative of Archer, which has anattack range of 2(measured by Manhattan distance), and an attack damage of 4. 
‘E’ : Representative of Ordinary soldier, which has anattack range of 1(measured by Manhattan distance), and an attack damage of 5. 
‘$’ : Representative of Liu Bei. 
‘!’ : Representative of Destination. 
'#' : Representative of obstacles 
‘.’ : Representative of floor. 
Liu Bei can not enter watchtower, forts, Archers, ordinary soldiers,But he can step onto flame or floor. 
Some important rules you should note: 
1.  Liu Bei will not be hurt by the same thing twice.For example,if Liu Bei has been hurt by one watchtower before,then he step into the attack range of some watchtower later,he will not be hurt. 
2.  When Liu Bei reach the destination,you should first judge the attack damage at the destination then finish the game. 
3.  You needn’t judge the attack damage at the start position. 
Please choose a path which LiuBei would cost the least HP. 

Input

In the first line there is an integer T, indicates the number of test cases.(T<=60) 
In each case,the first line of the input contains two integer n,m(1<=n,m<=50),reperesenting the size of map(n*m).Then follow n lines,each line contain m characters. 
There may be some blank lines between each case. 

Output

For each test case , output “Case d: “ where d is the case number counted from one.If Liu Bei can reach the destination then output the minimum HP LiuBei may lose, otherwise output -1.

Sample Input

1
4 3
.$.
ACB
ACB
.!.

Sample Output

Case 1: 6


本文发布于:2024-01-31 11:24:34,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170667147928169.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:队列   做法   HDU   非状压   Kingdoms
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23