笨笨熊搬家交通篇

森林里的苯苯熊要乔迁新喜,上次他已经将物品打包完成,并约了朋友来帮忙。接下来他要选定一个搬家的时间,想了很久,就决定在国庆节进行,因为国庆放假朋友们都有时间啦。但是在森林里,从他现在房子到新豪宅,所经之地有山有水,路途曲折,甚至有些道路是不通的。
       请你和他一起查看指定的地图,看看从笨笨熊现在的房子到新宅之间,道路是否是畅通的呢?
       地图是R行、C列的矩阵,矩阵的每一个格子刚好是一天的行程。
       矩阵由“B”、“-”、“#”、“H”四种字符成员组成,其中:
       B: 代表苯苯熊现在的房子;
       H: 代表笨笨熊新的豪宅;
       -: 代表可以通行的道路;
       #: 代表无法通过的障碍(高山、大河等);
       此外,森林里也有交通规则地:在任务位置,只能向“上、下、左、右”四个方向中的其中一个方向行走。

输入:

4  // R的数值
4  // C的数值,下面是地图。
--##---
B-----H
#---#--
-------

输出:

Y //代表道路可达
或 
N //代表道路不通

样例输入:

1

5

-B-H#

样例输出:

Y



Beta1

//*******************************************************************
//
// 笨笨熊搬家
// 作者:Davidlee
// 时间:2014_8_4
// 思路:找到元素B的所有连通分量,若其中包含H则可以到达
//
//*******************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

struct pos
{
   int x;
   int y;
};

int Go_through (pos *data,pos x,int n) //寻找data中前n个元素中是否已有x
{
  int z=0;
  int i;
  for(i=0;i<n;i++)
  {
      if((x.x==data[i].x)&&(x.y==data[i].y))
	  {
	    z=1;
	  }
  }
  return z;
}

void main()
{
    int ver_data,hor_data;
	int i,j,k_last,k_count,k_num,k_temp;
	int N;
	int z;
	pos temp_z;
	pos pos_B,pos_H;                                        //坐标

	scanf("%d",&ver_data);
	scanf("%d",&hor_data);

	N=ver_data*hor_data;									//存放位置,其最大值为ver_data*hor_data
	pos *store;
	store=(pos*)calloc(N,sizeof(pos));
	for (i=0;i<N;i++)
	{
		store[i].x=N;
		store[i].y=N;
	}                                          
	char **data;                                              //原始矩阵
	data=(char**)calloc(ver_data,sizeof(hor_data));
	for(i=0;i<ver_data;i++)
	{
	  data[i]=(char*)calloc(hor_data,sizeof(char));
	}

	for(i=0;i<ver_data;i++)
	{
		scanf("%s",data[i]);
	}

	for(i=0;i<ver_data;i++)									//寻找B,H坐标
	{
		for(j=0;j<hor_data;j++)
		{
			if(data[i][j]=='B')
			{
				pos_B.x=i;
				pos_B.y=j;
			}
			if(data[i][j]=='H')
			{
				pos_H.x=i;
				pos_H.y=j;
			}
		}
	}

	//初始化
	k_last=0;                                           
	k_count=1;		// k_count,上一次添加的新元素的个数;k_num,记录本次循环应该添加几个新元素;k_temp=k_last(上一次到第几个元素)+i								
	store[0]=pos_B;


	while (0!=k_count)  //k_count不为零表示上一次有新的连通分量加入,否则说明已经搜索过所有连通元素
	{
		k_num=0; 

		for(i=0;i<k_count;i++)
		{
			k_temp=k_last+i;   //本次小循环处理的元素
			//up;
			temp_z.x=store[k_temp].x-1;temp_z.y=store[k_temp].y;                           //查询该元素是否被已被录入store数组
			z=Go_through(store,temp_z,N);
			if(  ( (store[k_temp].x-1)>=0  ) && ((data[store[k_temp].x-1][store[k_temp].y])  != '#') && (z==0)     )//坐标录入条件:1 在正坐标系内 2 不是障碍(#)3 之前没被录入过
			{
				//k_num++;		        
				store[k_last+k_count+k_num].x=(store[k_temp].x-1);							//k_last+k_count为上一次处理的最后一个元素
				store[k_last+k_count+k_num].y=(store[k_temp].y);
				k_num++;
				
			}
			//down;
			temp_z.x=store[k_temp].x+1;temp_z.y=store[k_temp].y;							//查询该元素是否被已被录入store数组
			z=Go_through(store,temp_z,N);
			if(  ( (store[k_temp].x+1)<ver_data  ) && ((data[store[k_temp].x+1][store[k_temp].y])  != '#'  )&& (z==0)     )
			{
				//k_num++;				
				store[k_last+k_count+k_num].x=(store[k_temp].x+1);							//k_last+k_count为上一次处理的最后一个元素
				store[k_last+k_count+k_num].y=(store[k_temp].y);
				k_num++;
			
			}
			//left;
			temp_z.x=store[k_temp].x;temp_z.y=store[k_temp].y-1;
			z=Go_through(store,temp_z,N);//查询该元素是否被已被录入store数组
			if(  ( (store[k_temp].y-1)>=0  ) && ((data[store[k_temp].x][store[k_temp].y-1])  != '#' ) &&(z==0)     )
			{
				//k_num++;
				store[k_last+k_count+k_num].x=(store[k_temp].x);							//k_last+k_count为上一次处理的最后一个元素
				store[k_last+k_count+k_num].y=(store[k_temp].y-1);
				k_num++;

			}
			//right;
			temp_z.x=store[k_temp].x;temp_z.y=store[k_temp].y+1;
			z=Go_through(store,temp_z,N);														//查询该元素是否被已被录入store数组
			if(  ( (store[k_temp].y+1)<hor_data  ) &&( (data[store[k_temp].x][store[k_temp].y+1])  != '#') && (z==0)     )
			{	
				//k_num++;
				store[k_last+k_count+k_num].x=(store[k_temp].x);							//k_last+k_count为上一次处理的最后一个元素
				store[k_last+k_count+k_num].y=(store[k_temp].y+1);
				k_num++;

			}
		}
		k_last=k_last+k_count;
		k_count=k_num;

	}

	int sign=0;

	for(i=0;i<k_last;i++)
	{
	  if((store[i].x==pos_H.x)&&(store[i].y==pos_H.y))
	  {
	     sign=1;
	  }
	}

	if(sign==1)
	{
	   printf("Y\n");
	}
	else
	{
	   printf("N\n");
	}

	system("pause");

}





<pre name="code" class="cpp">//*******************************************************************
//
// 笨笨熊搬家.beta2
// 作者:Davidlee
// 时间:2014_10_12
// 思路:找到元素B的连通分量,若其中包含H则可以到达,优化了终止条件,不必将所有连通分量都查找,找到H的位置便可以终结循环
//      
//*******************************************************************
#include <iostream>
using namespace std;
#include <Windows.h>
#include <vector>

struct pos
{
	int x;
	int y;
};

int n=1;        //全局变量,连通数组的大小
pos PosH_end;   //全局变量,用于表示连通数组中添加了pos_B,用于结束查询
int SearchThrough(pos *data,pos x)  //0表示添加过
{
	int z=1;
	int i;
	for(i=0;i<n;i++)
	{
		if((x.x==data[i].x)&&(x.y==data[i].y))
		{
			z=0;
		}
	}
	return z;
}

int LookFor(pos x, char **dmap,pos *data)
{
	int z=0;
	int z1=0,z2=0;
	if((dmap[x.x][x.y]=='-')||dmap[x.x][x.y]=='H'){z1=1;}  //路通
	z2=SearchThrough( data,x);   //没添加过

	z=z1*z2;
	return z;
}

int QuickFind(pos x,char **dmap,int Row, int Column,pos *data)
{
	int z=0;
	pos temp;
	if((x.y-1)>=0) //Left
	{
	   temp=x;temp.y=temp.y-1;
	   if ( (z=LookFor(temp,dmap,data))==1  ){ if((temp.x==PosH_end.x)&&(temp.y==PosH_end.y)){n++;return 0;}data[n]=temp;n++;QuickFind(temp,dmap,Row,Column,data);}  //调用自身,实现的是连通数组的增长
	};                                         //若检测到H已经进入连通数组,则终止查找

	if((x.y+1)<Column) //Right
	{
		temp=x;temp.y=temp.y+1;
		if ( (z=LookFor(temp,dmap,data))==1  ){if((temp.x==PosH_end.x)&&(temp.y==PosH_end.y)){n++;return 0;}data[n]=temp;n++;QuickFind(temp,dmap,Row,Column,data);}
	};

	if((x.x-1)>=0) //Up
	{
		temp=x;temp.x=temp.x-1;
		if ( (z=LookFor(temp,dmap,data))==1  ){if((temp.x==PosH_end.x)&&(temp.y==PosH_end.y)){n++;return 0;}data[n]=temp;n++;QuickFind(temp,dmap,Row,Column,data);}
	};

	if((x.x+1)<Row) //Down
	{
		temp=x;temp.x=temp.x+1;
		if ( (z=LookFor(temp,dmap,data))==1  ){if((temp.x==PosH_end.x)&&(temp.y==PosH_end.y)){n++;return 0;}data[n]=temp;n++;QuickFind(temp,dmap,Row,Column,data);}
	};

	return 0;
}

int main()
{
  int i,j;
  int row,column;
  int sign;
  pos pos_B, pos_H;
 
  cin>>row;
  cin>>column;

  pos *Linkin=(pos *)calloc(row*column,sizeof(pos));  //不能用new

  char **map;
  map=new char*[row];
  for(i=0; i<row; i++)
  { map[i]=new char[column];}

  for(i=0; i<row; i++)
  {
    for(j=0; j<column; j++)
	{
	   cin>>map[i][j];
	   if(map[i][j]=='B'){pos_B.x=i;pos_B.y=j;}
	   if(map[i][j]=='H'){pos_H.x=i;pos_H.y=j;}
	}
  }

  PosH_end=pos_H;

  cout<<"pos_B="<<pos_B.x<<"  "<<pos_B.y<<endl;
  cout<<"pos_H="<<pos_H.x<<"  "<<pos_H.y<<endl;

  
  Linkin[0]=pos_B;
  QuickFind(pos_B,map,row,column,Linkin);

  sign=SearchThrough(Linkin,pos_H);

  if(sign){cout<<"No"<<endl;}  //sign==0,表示添加了pos_H
  else{cout<<"Yes"<<endl;}

  cout<<n<<endl;

  system("pause");
  return 0;
}

 











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值