hdu3533 炮弹迷宫问题

每日打卡(1/1) (补:昨天生病了)

传送门:点击打开链接

题目大意:

    地图上有若干门大炮,每门大炮有个朝向,隔若干时间会发射一枚炮弹,炮弹有速度,只能停在格点上。问人从起点到终点,要求不被大炮打中,可以在某点停留不动,问到终点最少要多少时间;

题目思路:

    由于这题数据是有一定问题的,在方向问题上面搞了很久,最后发现是题目的问题。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 105;

struct node{
	int dir,x,y,t,v;
}E[1005];
bool vis[maxn][maxn][1005],map[maxn][maxn],hav[maxn][maxn][1005];//hav数组:x,y,t
int n,m,k,d;
int dir[5][2] = {0,1,0,-1,1,0,0,-1,0,0};

struct Node{
	int x,y,tot;
};
void pre()//首先预处理,用三维数组hav模拟炮弹时空位置
{
	memset(hav,0,sizeof(hav));
	for(int i=0;i<k;i++)
	{
		for(int j=0;j<=d;j+=E[i].t)
		{
			for(int l=1;;l++)
			{
				int x = E[i].x+dir[E[i].dir][0]*l;
				int y = E[i].y+dir[E[i].dir][1]*l;
				if(x<0||x>n||y<0||y>m||map[x][y]) break;
				if(l%E[i].v==0) {
					hav[x][y][j+l/E[i].v] = true;
				}
			}
		}
	}	
}

int bfs()//宽搜
{
	queue<Node> q;
	while(!q.empty()) q.pop();
	memset(vis,0,sizeof(vis));
	Node a;
	a.x = 0;
	a.y = 0;
	a.tot = 0;
	q.push(a);
	vis[0][0][0] = 1;
	while(!q.empty())
	{
		a = q.front();
		q.pop();
		if(a.tot>d) return -1;
		if(a.x==n&&a.y==m)
		 return a.tot;
		for(int i=0;i<5;i++)
		{
			Node next;
			next.x = a.x+dir[i][0];
			next.y = a.y+dir[i][1];
			next.tot = a.tot+1;
			if(next.x<0||next.y<0||next.x>n||next.y>m||vis[next.x][next.y][next.tot]||map[next.x][next.y]||hav[next.x][next.y][next.tot]) continue;
			q.push(next);
			vis[next.x][next.y][next.tot] = 1;
		}
	}
	return -1;
	
}

int main()
{
	while(scanf("%d%d%d%d",&n,&m,&k,&d)!=EOF)
	{
		memset(map,0,sizeof(map));
		memset(vis,0,sizeof(vis));
		char s;
		for(int i=0;i<k;i++)
		{
			getchar();
			scanf("%c",&s);
			if(s=='N') E[i].dir = 0;
                        if(s=='S') E[i].dir = 1;
                        if(s=='E') E[i].dir = 2;
                        if(s=='W') E[i].dir = 3;
			scanf("%d%d%d%d",&E[i].t,&E[i].v,&E[i].y,&E[i].x);
			map[E[i].x][E[i].y] = 1;
		}
		pre();
		int ans = bfs();
		if(ans==-1) {
			cout<<"Bad luck!"<<endl;
		}
		else {
			cout<<ans<<endl;
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

总想玩世不恭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值