hdu 2531

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

依旧广搜,要注意的是防守队员身体可能占到25格...之前没注意到这个WA了几次

code:

#include <iostream>
#include "queue"
#include "memory.h"
using namespace std;
char map[105][105];		//地图 
int vit[105][105];
int n,m;
int flag;			//是否能够碰到后分卫 
int resulta;
int stothersum;			//身体的其他占位 
int fangxiang[4][2]={-1,0,1,0,0,-1,0,1};

struct point
{
	int x;
	int y;
};
struct shengti
{
	point tou;
	point otherr[35];	//其他35个身体占位 
	int step;
	
};
queue <shengti> q;
int cango(int x,int y)
{
	if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]!='O')		//没超过边界且没碰到防守人 
	{
		return 1;
	}
	return 0;
}
void bfs(void)
{
	while(!q.empty())	//队列不为空 
	{
		
		shengti temp=q.front();
		q.pop();
		if(flag==1)		//已经找到答案 
		{
			return;
		}
		int stpq=0;
		int sti2;
		for(sti2=0;sti2<stothersum;sti2++)
		{
			if(map[temp.otherr[sti2].x][temp.otherr[sti2].y]=='Q')	//身体其他部位有碰到Q 
			{
				stpq=1;
				break;
			}
		}
		if(map[temp.tou.x][temp.tou.y]=='Q'||stpq==1)	//头或脚碰到后分卫则退出 
		{	
			flag=1;
			resulta=temp.step;
			return ;
		//	return temp.step;		//返回步数 
		}
		int i;
		int toux=temp.tou.x;		//头脚坐标都取出 
		int touy=temp.tou.y;
		//int jiaox=temp.jiao.x;
		//int jiaoy=temp.jiao.y;
		
		for(i=0;i<4;i++)	//四个方向广搜 
		{
		
			int hnewx,hnewy,jnewx,jnewy;
			hnewx=toux+fangxiang[i][0];
			hnewy=touy+fangxiang[i][1];
			int sti;
			int flagst=0; //判断身体其他部位的合法性 
			for(sti=0;sti<stothersum;sti++)
			{
				jnewx=temp.otherr[sti].x+fangxiang[i][0];
				jnewy=temp.otherr[sti].y+fangxiang[i][1];
				if(!cango(jnewx,jnewy))
				{
					flagst=1;
					break;
				}
			}
			if(cango(hnewx,hnewy)&&!flagst&&vit[hnewx][hnewy]==0)	//没超过连界且没碰到防守人且该新头坐标没被访问过 
			{
				vit[hnewx][hnewy]=1;
				shengti stn;
				stn.tou.x=hnewx;
				stn.tou.y=hnewy;
				//stn.jiao.x=jnewx;
				//stn.jiao.y=jnewy;
				int stf;
				for(stf=0;stf<stothersum;stf++)			//身体其他部位赋新值 
				{
				stn.otherr[stf].x=temp.otherr[stf].x+fangxiang[i][0];
				stn.otherr[stf].y=temp.otherr[stf].y+fangxiang[i][1];
				
				}
				stn.step=temp.step+1;
				q.push(stn);			//新结点加入队列 
				
			}
			
		}
		
	}
}
int main(int argc, char *argv[])
{

	while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)
		{
			break;
		}
		while(!q.empty())	//队列清空 
		{
			q.pop();
		}
		memset(vit,0,sizeof(vit));	//访问清空 
		int i,j;
		shengti st;			//防守队员身体
		st.tou.x=-1; 
		stothersum=0;
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				cin>>map[i][j];		//输入地图信息 
				if(st.tou.x==-1&&map[i][j]=='D')	//输入头尾信息 
				{
					st.tou.x=i;
					st.tou.y=j;
					map[i][j]=1;
					
				}else if(map[i][j]=='D')
				{
					st.otherr[stothersum].x=i;
					st.otherr[stothersum].y=j;
					stothersum+=1;			//身体的其他战位 
				}
			}
			
		}
			st.step=0;	
			q.push(st);
			flag=0;
			bfs();
			if(flag==0)
			{
				printf("Impossible\n");
			}else
			{
				printf("%d\n",resulta);
			}
		
	}
	return 0;
}

 

转载于:https://my.oschina.net/hlslml77/blog/180668

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值