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