解题感悟:
- 将数组开大一点( 并从 (1, 1) 开始存方阵 )可以避免过多的验证数组下标验证;
- 本题适合使用BFS方法来解;
#include<stdio.h>
#include<string.h>
#define MAXN 25
char room[MAXN][MAXN];
int list[1000]={0};
int temp[1000]={0};
int row,col,sum;
int i,j,k;
void bfs(int num);
int main(void){
while(scanf("%d %d",&col,&row) && col && row){
memset(room,'#',sizeof(room));
memset(list,0,sizeof(list));
memset(temp,0,sizeof(temp));
for(i = 0;i < row;++i )
scanf("%s",room[i]+1);
for(k = 1;k <= row*col;++k){ //通过 k 可算出 横纵坐标
i = k / col;
j = k % col;
/* 这有个问题,当k表示数组最后一列元素时,
* i,j算出来是下一行的首个元素,
* 但这并不是我们想要的,这种情况下十分有必要重新赋值,
* 否则一定会 **WA** 的 。╮( ̄▽ ̄)╭,
* 如果使用两层for循环分别表示横纵坐标的话不会出现这种情况;
*/
if(!j){
j = col;
i--;
}
if(room[i][j]== '@'){
room[i][j] = '#';
list[0]= k;
break;
}
}
sum = 1;
bfs(1);
printf("%d\n",sum);
}
return 0;
}
void bfs(int num){
int count;
while(num){
for(k = 0,count = 0;k<num;++k){
i = list[k] / col;
j = list[k] % col;
if(!j){
j = col;
i--;
}
if(room[i+1][j] == '.'){
room[i+1][j] = '#';
temp[count++] = list[k] + col;
}
if(i && room[i-1][j] == '.'){
room[i-1][j] = '#';
temp[count++] = list[k] - col;
}
if(room[i][j+1] == '.'){
room[i][j+1] = '#';
temp[count++] = list[k] + 1;
}
if(room[i][j-1] == '.'){
room[i][j-1] = '#';
temp[count++] = list[k] - 1;
}
}
for(i = 0,num = count;i < count;++i)
list[i] = temp[i];
sum += num;
}
}