hdu2612 Find a way

原文链接: hdu2612 Find a way

上一篇: 输出矩阵的周围元素

下一篇: 分油

map[aa.x][bb.y]这里应该是map[aa.x][aa.y]才对,当时不知道为什么会写成那样,而且能通过,更不得其解,但是后来改回来以后,提交竟然通不过了!为这个问题困扰了两天!下午,让老师帮我看看。后来老师出了一个神测试数据。
4 5
@.#@.
..Y#.
@#M#.
@..#@
      这个测试数据用我改后的代码竟然输出为0,后来用别人的其他能在航电上通过的代码测试,输出也是0,但该测试数据结果应该为77才对。这就说明了该题后台测试数据不全面。
后来想了想为什么会输出为0,该测试数据很特殊,因为第四列@和第五列的@在广搜时搜不到!因为被墙#完全隔着,其步数永远是0,后来在遍历全图,取两人在@处最小步数时,肯定是没有搜到的@处最小,因为二者到此处的步数均为0,想加也为0,所以必须得加一个限制条件,取@处二者步数相加和的最小且该@处必须已经被搜过!加上这一句,代码就没问题了。我把上面提到的错误(map[aa.x][bb.y]这里应该是map[aa.x][aa.y]才对)改了以后,又在后面加上了限制条件,再重新提交,Ac了!哎,不容易啊,一桩心事终于了了!
下面附上修改后并优化后的代码:
#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;
int n,m;
char mp[222][222];
int dir[4][2]={-1,0,1,0,0,-1,0,1};
bool vis[2][222][222];
int dis[2][222][222];

struct Node{
	int k,x,y,step;
	Node(){ }
	Node(int x,int y,int step):x(x),y(y),step(step){} 
};

void setVis(Node& a){
	vis[a.k][a.x][a.y]=1;
}

bool check(Node& a){
	return a.x<n && a.y<m && a.x>=0 && a.y>=0 && vis[a.k][a.x][a.y]==0 && mp[a.x][a.y]!='#';
} 
void bfs(Node& start){
	queue<Node> q;
	q.push(start);
	setVis(start);
	
	while( !q.empty() ){
		Node t = q.front();
		q.pop();
		if(mp[t.x][t.y]=='@'){
			dis[t.k][t.x][t.y]=t.step;
		}
		
		//上下左右 
		Node next; 
		for(int k=0;k<4;k++){
			next.k=t.k;
			next.x=t.x+dir[k][0];
		 	next.y=t.y+dir[k][1];
		 	next.step=t.step+1;
		 	if(check(next)){
				q.push(next);
				setVis(next); 
		 	}
		}
	}
}
int main(int argc, char *argv[])
{
	while (scanf("%d %d",&n,&m)==2 ){
		memset(vis,0,sizeof(vis));
		for(int i=0;i<n;i++)
			scanf("%s",mp[i]);
						
		Node ystart,mstart;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(mp[i][j]=='Y'){
					ystart.k=0,ystart.x=i,ystart.y=j,ystart.step=0;
				}
				if(mp[i][j]=='M'){
					mstart.k=1,mstart.x=i,mstart.y=j,mstart.step=0;
				}
			} 
		}
	
		//分别广搜 
		bfs(ystart);
		bfs(mstart);
		int mincnt=1<<20;
		 
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++){
				if(mp[i][j]=='@' && vis[0][i][j]==1 && vis[1][i][j]==1 && mincnt>dis[0][i][j]+dis[1][i][j])
					mincnt=dis[0][i][j]+dis[1][i][j];
			
			}
		printf("%d\n",mincnt*11);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值