背景:周赛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];}
简化代码量。
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);
}
}