现在的位置: 首页 > 综合 > 正文

hdu 1312简单bfs

2018年01月12日 ⁄ 综合 ⁄ 共 2268字 ⁄ 字号 评论关闭

背景:周赛c题,写好代码40分钟,然后一直调不通,调到还剩3分钟比赛结束的时候突然返现step写法错误,快速该,最后102s提交ac!!!!太刺激了。

学习:

1.开始一直调试了好久就是字符串的读入有问题,没有在意在用getchar读取字符串时对‘\n'的处理。

2.思想依然没有十分严谨的把一个问题过程全部理清楚就去写代码,最后又花很久时间去调试,这是很得不偿失的。比如这里ha的归0开始就没有想到。

3.其实这里可以用一个字符串数组来读取

for(int i=0;i<w;w++)
 scanf("%s",map[w]);

4.其实这个题用dfs也可以,空间占用小或许hdu上的0k就是dfs吧。

5.这里我用两个数组来倒腾,其实可以用STL中的queue(数据结构),这样对于每一个front元素都检测它的四个方向把可行的下几个方向push入队尾,然后把队首pop出去

。(#include<queue>     using namespacestd;)

6.代码中用四个if语句来表示四个方向实在太不简洁了。用一个:
int str[4][2]={1,0,0,1,-1,0,0,-1};
for(int i=0;i<4;i++)  {x=x+str[i][[0]; y=y+str[i][1];}

简化代码量。

#include<stdio.h>
#include<string.h>
int map[21][21],w,h,step,ha,hb;//ha,hb分别代表a,b数组高度 
bool cona(void);
bool conb(void);
struct place
{
	int x;
	int y;
}a[100],b[200];
  bool cona(void)//对于a中每一个位置扫描四个方向,能走的位置都储存在b数组中,并把可到达的位置加上数加上ha。 
  {
  	for(int ii=0;ii<ha;ii++)
  	{
	  	if(map[a[ii].x+1][a[ii].y]=='.')
	  	{
	  		map[a[ii].x+1][a[ii].y]='#';//把走过了的位置设置为#. 
	  		b[hb].x=a[ii].x+1;
	  		b[hb].y=a[ii].y;
	  		hb++;
	  	}
	  	if(a[ii].x-1>=0&&map[a[ii].x-1][a[ii].y]=='.')
	  	{
	  		map[a[ii].x-1][a[ii].y]='#';
	  		b[hb].x=a[ii].x-1;
	  		b[hb].y=a[ii].y;
	  		hb++;
	  	}
	  	if(a[ii].y-1>=0&&map[a[ii].x][a[ii].y-1]=='.')
	  	{
	  		map[a[ii].x][a[ii].y-1]='#';
	  		b[hb].x=a[ii].x;
	  		b[hb].y=a[ii].y-1;
	  		hb++;
	  	}
	  	if(map[a[ii].x][a[ii].y+1]=='.')
	  	{
	  		map[a[ii].x][a[ii].y+1]='#';
	  		b[hb].x=a[ii].x;
	  		b[hb].y=a[ii].y+1;
	  		hb++;
	  	}
    }
    step+=ha;
    ha=0;//清空a数组。 
    if(hb==0) return true;//如果无路可走返回true。 
    else  return false; 
  }
  bool conb(void)
  {
  	for(int ii=0;ii<hb;ii++)
  	{
	  	if(map[b[ii].x+1][b[ii].y]=='.')
	  	{
	  		map[b[ii].x+1][b[ii].y]='#';
	  		a[ha].x=b[ii].x+1;
	  		a[ha].y=b[ii].y;
	  		ha++;
	  	}
	  	if(b[ii].x-1>=0&&map[b[ii].x-1][b[ii].y]=='.')
	  	{
	  		map[b[ii].x-1][b[ii].y]='#';
	  		a[ha].x=b[ii].x-1;
	  		a[ha].y=b[ii].y;
	  		ha++;
	  	}
	  	if(b[ii].y-1>=0&&map[b[ii].x][b[ii].y-1]=='.')
	  	{
	  		map[b[ii].x][b[ii].y-1]='#';
	  		a[ha].x=b[ii].x;
	  		a[ha].y=b[ii].y-1;
	  		ha++;
	  	}
	  	if(map[b[ii].x][b[ii].y+1]=='.')
	  	{
	  		map[b[ii].x][b[ii].y+1]='#';
	  		a[ha].x=b[ii].x;
	  		a[ha].y=b[ii].y+1;
	  		ha++;
	  	}
    }
    step+=hb;
    hb=0;
    if(ha==0)  return true;
    else  return false; 
  }


int main(void)
{
	while(scanf("%d%d",&h,&w)&&w+h)
	{   
	    step=0;
	    ha=1;//a数组中有一个元素为起始位置。 
	    hb=0;
		memset(map,'#',sizeof(map));//把这个图全部化为'#'这样就不会走到可走棋盘之外的地方了。 
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		int ll=0; 
		for(int i=0;i<w;i++)
		{    
		    getchar();//读取上一组数据之后的换行符。- 
			for(int j=0;j<h;j++) map[i][j]=getchar() ;
			ll++;
		}
		for(int i=0;i<w;i++) //扫全图读取起始位置。 
		{
			for(int j=0;j<h;j++)
			{
				if(map[i][j]=='@')
				{
					a[0].x=i;
					a[0].y=j;
				goto l1;
				}
			}
			
		}
l1:	while(1)
		{
			if(cona()) break;
			if(conb()) break;
		}
		printf("%d\n",step);	
	}
} 

【上篇】
【下篇】

抱歉!评论已关闭.