您的位置:首页 > 其它

HDU3533(Escape)

2016-02-23 17:56 239 查看
不愧是kuangbin的搜索进阶,这题没灵感写起来好心酸

思路是预处理所有炮台射出的子弹,以此构造一个三维图(其中一维是时间)

预处理过程就相当于在图中增加了很多不可到达的墙,然后就是一个简单的bfs

此题难点也是预处理过程,还有就是注意可以停在原地也就是有5个方向

然后就是建图用bool类型,不然可能会爆内存。
http://acm.hdu.edu.cn/showproblem.php?pid=3533
AC: 405ms 11608kb

#include<iostream>
#include<sstream>
#include<stack>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cctype>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
#define N 150

using namespace std;

int n,m,ans,energe;          //energe所给的总时间
int dir[5][2]= {{-1,0},{0,-1},{1,0},{0,1},{0,0}};   //(0,0)留在原地
bool pic[101][101][1001];
struct GUN{
short int x,y;
short int dir;          //炮台方向
short int period;       //炮台发射子弹的周期
short int velocity;     //子弹速度
} gun[101];
struct NODE{
short int x,y;
short int eng;      //当前所耗时间
}node,temp;

void init(int &group)   //预处理(参考HUSToj上ID为ENDIF的代码)
{
for(int i=0; i<group; ++i)
{
int state=0;    //子弹走过的路程
int x=gun[i].x;int y=gun[i].y;
int dd=gun[i].dir;
while(1)
{
++state;
x+=dir[dd][0];y+=dir[dd][1];
if(x<0||x>n||y<0||y>m||(!pic[x][y][0])) break;   //有炮台,子弹会被阻挡
if(!(state%gun[i].velocity))        //如果子弹在整数时间内到达某可达位置
{                                   //则进行图的预处理(增加不可到达的“墙”)
for(int j=state/gun[i].velocity; j<=energe; j+=gun[i].period)
pic[x][y][j]=false;
}
}
}
}

bool bfs()
{
queue<NODE>q;
node.x=0; node.y=0;
node.eng=0;
q.push(node);
while(!q.empty())
{
node=q.front(); q.pop();
if(node.x==n&&node.y==m)
{
ans=node.eng;
return true;
}
if(node.eng==energe) return false;
if(n-node.x+m-node.y>energe-node.eng) continue;   //曼哈顿距离剪枝
temp=node;
++temp.eng;
for(int i=0; i<5; ++i)
{
temp.x=node.x+dir[i][0];
temp.y=node.y+dir[i][1];
if(temp.x<0||temp.x>n||temp.y<0||temp.y>m||(!pic[temp.x][temp.y][temp.eng]))
continue;
pic[temp.x][temp.y][temp.eng]=false;
q.push(temp);
}
}
return false;
}

int main()
{
//freopen("lxx.txt","r",stdin);
int group;
char ch;
while(scanf("%d%d%d%d",&n,&m,&group,&energe)!=EOF)
{
memset(pic,true,sizeof(pic));
for(int i=0; i<group; ++i)
{
scanf(" %c",&ch);
if(ch=='N') gun[i].dir=0;
else if(ch=='W') gun[i].dir=1;
else if(ch=='S') gun[i].dir=2;
else gun[i].dir=3;
scanf("%hd%hd%hd%hd",&gun[i].period,&gun[i].velocity,&gun[i].x,&gun[i].y);
for(int j=0; j<=energe; ++j)
pic[gun[i].x][gun[i].y][j]=false;
}
init(group);
if(!bfs()) printf("Bad luck!\n");
else printf("%d\n",ans);
}
return 0;
}


努力向高级搜索迈进!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: