zoj 1671 Walking Ant

zoj 1671 Walking Ant

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<iomanip>
#include<string>
#include<algorithm>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#define N 10
using namespace std;
class ANT
{public:int step,hp,x,y;};
int map[N][N],dir[4][2]={0,1,0,-1,1,0,-1,0};
int m,n,hp[N][N];
ANT ant,antin;
queue<ANT>q;
bool legal(ANT &ant)
{if(ant.x>=1&&ant.x<=m&&ant.y>=1&&ant.y<=n)return true;return false;}
int BFS()
{
	int i;		
	while(!q.empty())
	//总体来讲只有当蚂蚁活着的时候其路径才会入队列
	//所以当队列空的时候还没找到出口那么该蚂蚁一定是死在了回巢的路上直接返回-1即可
	{
			    ant=q.front();q.pop();
				if(ant.hp==0) continue;//hp==0不再考虑,蚂蚁死掉,再考虑无意义
				for(i=0;i<4;i++)
				{
					antin.x=ant.x+dir[i][0];antin.y=ant.y+dir[i][1];antin.step=ant.step+1;//转向步长加一
					if(legal(antin)&&map[antin.x][antin.y]>=1&&ant.hp-1>hp[antin.x][antin.y])
					//若当前位置合法,地图上显示可走,
					//即使是当前位置上没有食物该蚂蚁hp也比上一次经过这里时剩余的hp多
					{
						if(map[antin.x][antin.y]==3)//找到nest返回
							return antin.step;
						/*
						*只有两种情况路径才会入队列
						*一是有食物(4)
						*二是本来就是可走路径(1)
						*起始位置(2)不用再走因为起始位置hp为6转了一圈又回到起始位置是不划算的
						*/
						if(map[antin.x][antin.y]==4)
						{
							antin.hp=6;
							hp[antin.x][antin.y]=6;
							q.push(antin);
						}
						if(map[antin.x][antin.y]==1)
						{
							hp[antin.x][antin.y]=antin.hp=ant.hp-1;
							q.push(antin);
						}
					}
				}
	}
	return -1;
}
int main()
{
     ///  freopen("input.txt","r",stdin);
      // freopen("output.txt","w",stdout);
	   int nestx,nesty,i,j; 
	   while(cin>>n>>m&&n&&m)
	   {
			while(!q.empty()) q.pop();//清空队列
		   memset(hp,0,sizeof(hp));
		   for(i=1;i<=m;i++)
			{
				for(j=1;j<=n;j++)
				{
					cin>>map[i][j];
					if(map[i][j]==2)//确定起始位置
					{//初始化
						ant.x=i;ant.y=j;ant.hp=6;ant.step=0;
						q.push(ant);
						hp[i][j]=6;
					}
				}
			}
			cout<<BFS()<<endl;
	   }
		return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注