HDU 2653 Waiting ten thousand years for Love

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

#include<iostream>
#include<queue>
using namespace std;
#define N 81
bool h[N][N][N];
int dir[4][2]={-1,0,0,-1,1,0,0,1};
struct node{
	int x,y;
	int step;
	int pow;
	bool friend operator< (const node &a,const node& b){
		if(a.step==b.step)
			return a.pow<b.pow;
		return a.step>b.step;
	}
};
char map[N][N];
int n,m,T,P;
int fx,fy;
bool judge(node p){
	if(p.x>=0&&p.x<n&&p.y>=0&&p.y<m&&map[p.x][p.y]!='#')
		return true;
	return false;
}
void bfs(){
	priority_queue<node> q;
	node temp,p;
	p.x=fx;p.y=fy;
	p.step=0;
	p.pow=P;
	memset(h,0,sizeof(h));
	q.push(p);
	h[fx][fy][P]=1;
	while(!q.empty()){
		temp=q.top();
		q.pop();
		if(map[temp.x][temp.y]=='L'){
			if(temp.step<=T){
				printf("Yes, Yifenfei will kill Lemon at %d sec.\n",temp.step);
				return;
			}
			break;
		}
		//fly//
		if(temp.pow>0){
			for(int i=0;i<4;i++){
				p=temp;
				p.x+=dir[i][0];
				p.y+=dir[i][1];
				p.step++;
				p.pow--;
				if(judge(p)&&!h[p.x][p.y][p.pow]){
					h[p.x][p.y][p.pow]=1;
					q.push(p);
				}
			}
		}
		//work//
		if(map[temp.x][temp.y]=='@')
			continue;
		for(int i=0;i<4;i++){
			p=temp;
			p.x+=dir[i][0];
			p.y+=dir[i][1];
			p.step+=2;
			if(judge(p)&&!h[p.x][p.y][p.pow]){
				if(map[p.x][p.y]=='@') continue;
				h[p.x][p.y][p.pow]=1;
				q.push(p);
			}
		}
	}
	printf("Poor Yifenfei, he has to wait another ten thousand years.\n");
}	
int main(void){
	int k=1;
	while(~scanf("%d%d%d%d",&n,&m,&T,&P)){
		for(int i=0;i<n;i++){
			scanf("%s",map[i]);
			for(int j=0;j<m;j++)
				if(map[i][j]=='Y'){
					fx=i;
					fy=j;
				}
		}
		printf("Case %d:\n",k++);
		bfs();
	}
}

太经典啦!刚开始还想着要是走到的是‘@’,那不是得再从此点往四周扩展,但是扩展的途中又会遇到'@',此时不是又得继续扩展吗?好麻烦!!> . <

无奈,百度了一下,看了AC大大的,恍然大悟啊!完全不用扩展下去的,每次分为fly 或者 work 两种,fly 没什么特别的要求,但是work 的话有两个,一个如果当前点是'@'的话不能work (!!!就是这里经典啊!!),还有不要忘记如果扩展出去的是'@'的话,那也是不行的,因为你是要走过去的,'@'要求是fly才能到达的。。。。主要是思考如果当前点是'@'的话,如何扩展,知道方法了自然觉得简单,但是自己思考的时候就往复杂的想了,比如想着不能把‘@’这个点入队,应该由这个点扩展下去的点入队,这样就很麻烦了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值