---
# System prepended metadata

title: 找路

---

# 找路
:::info
因為對struct不熟，所以就用array來模擬queue
結果WA，只過兩個測資

11/05 20:42 Update:
經過助教指點我重新寫了一下fp_x和fp_y的實作方式
並把判斷depth++的地方移到bfs的最前面判斷
成功過前面四個測資了
但最後一個還是WA
:::
### 思路
![](https://i.imgur.com/zOkRefy.jpg)
![](https://i.imgur.com/tkhCKqO.jpg)
## submit 結果
### 新submit結果
![](https://i.imgur.com/XNzHeVh.png)

舊:
![](https://i.imgur.com/eLin5ka.png)
# 新code
## pure
```c
#include<stdio.h>
#include<stdbool.h>
int q_start = 0, q_end = 0/*the index of last value +1*/;
int row, col;
int fp_x = -1;
int fp_y = -1;

void q_push(int val, int q[]){
  if(q_start <= q_end){
    q[q_end] = val;
  }
  else{
    printf("buffer saturated during push\n");
  }
}

int q_pop(int q[]){
  if(q_start <= q_end){
    return q[q_start];
  }
  else{
    printf("buffer saturated during pop %d\n",q_start);
    return -1;
  }
}

int bfs(int map[][col], int x, int y, int depth, int q_x[], int q_y[], bool visited[][col],bool dep_chg){
  if(dep_chg)
     depth++;
  if(map[y][x] == -3){//end condition
    printf("%d\n",depth-1);//depth includes the first block
    return -1;//pop out this function
  }
  else{
    //put the next level value into queue then pop
    //push if pathable and in range and not visited
    if(dep_chg){//if enter next level
      fp_x = -1;//first push x
      fp_y = -1;
    }
    if(x-1 >= 0 && y >= 0 && x-1 < col && y < row && map[y][x-1] != -1 && !visited[y][x-1]){
      //push into queue
      q_push(x-1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x-1] = true;
	  if(fp_x == -1){
		fp_x = x-1;
		fp_y = y;
	  }
    }
    if(x+1 >= 0 && y >= 0 && x+1 < col && y < row && map[y][x+1] != -1 && !visited[y][x+1]){
      //push into queue
      q_push(x+1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x+1] = true;
      if(fp_x == -1){
        fp_x = x + 1;
        fp_y = y;
      }
    }
    if(x >= 0 && y-1 >= 0 && x < col && y-1 < row && map[y-1][x] != -1 && !visited[y-1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y-1, q_y);
      q_end++;
      visited[y-1][x] = true;
        if(fp_x == -1){
          fp_x = x;
          fp_y = y - 1;
        }
    }
    if(x >= 0 && y+1 >= 0 && x < col && y+1 < row && map[y+1][x] != -1 && !visited[y+1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y+1, q_y);
      q_end++;
      visited[y+1][x] = true;
      if(fp_x == -1){
        fp_x = x;
        fp_y = y + 1;
      }
    }
    int next_x = q_pop(q_x);
    int next_y = q_pop(q_y);
    q_start++;

    bool whether_next;
    if(next_x != fp_x || next_y != fp_y)
      whether_next = false;
    else
      whether_next = true;
    if(next_x != -1 && next_y != -1){
      if(!whether_next)
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited, false);
      else
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited, true);
    }
    //printf("leave bfs\n");
  }
}

int main(int argc, char *argv[]){
  scanf("%d %d",&row, &col);
  //0: pathable
  //-1: handicap
  //-2: start
  //-3: end
  int x_start, y_start;//the start point
  int map[row][col];
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      scanf("%d", &map[i][j]);
      if(map[i][j] == -2){
        x_start = j;
        y_start = i;
      }
    }
  }
  bool visited[row][col];
  for(int i = 0; i < row; i++){
    for(int  j = 0; j < col; j++){
        visited[i][j] = false;
    }
  }
  int depth = 0;
  int max_size = 1;//max_size of queue
  for(int i = (row + col); i >= (col+1); i--){
    max_size *= i;
  }
  for(int i = 1; i <= row; i++){
    max_size /= i;
  }
  //now max_size is C(row+col,row):max way
  max_size *= (row+col);//max_step:walk close to range
  int q_x[max_size];
  int q_y[max_size];
  for(int i = 0; i < max_size ; i++){
    q_x[i] = -1;
    q_y[i] = -1;
  }
  visited[y_start][x_start] = true;
  bfs(map, x_start, y_start, depth, q_x, q_y, visited, true);
  return 0;
}
```

## debug版
```c
#include<stdio.h>
#include<stdbool.h>
int q_start = 0, q_end = 0/*the index of last value +1*/;
int row, col;
int fp_x = -1;
int fp_y = -1;
//debug
void print_q(int q_x[],int q_y[]){
  printf("start print q\n");
  for(int i = q_start; i < q_end; i++){
    printf("%d ",q_x[i]);
  }
  printf("\n");
  for(int i = q_start; i < q_end; i++){
    printf("%d ",q_y[i]);
  }
  printf("\n");
}
//debug
void q_push(int val, int q[]){
  if(q_start <= q_end){
    q[q_end] = val;
  }
  else{
    printf("buffer saturated during push\n");
  }
}

int q_pop(int q[]){
  if(q_start <= q_end){
    return q[q_start];
  }
  else{
    printf("buffer saturated during pop %d\n",q_start);
    return -1;
  }
}

int bfs(int map[][col], int x, int y, int depth, int q_x[], int q_y[], bool visited[][col],bool dep_chg){

  //debug
  if(dep_chg)
    printf("call bfs(x:%d,y:%d,dep:%d,dep_chg: true)\n", x, y, depth);
  else
    printf("call bfs(x:%d,y:%d,dep:%d,dep_chg: false)\n", x, y, depth);
  //printf("fp_x:%d,fp_y:%d\n",fp_x,fp_y);
  //debug
  if(dep_chg)
     depth++;
  printf("depth after judge:%d\n",depth);
  print_vis(visited);//debug
  if(map[y][x] == -3){//end condition
    printf("%d\n",depth-1);//last depth has met the condition but print at next call
    return -1;//pop out this function
  }
  else{
    //put the next level value into queue then pop
    //push if pathable and in range and not visited
    if(dep_chg){//if enter next level
		fp_x = -1;//first push x
		fp_y = -1;
	}
    if(x-1 >= 0 && y >= 0 && x-1 < col && y < row && map[y][x-1] != -1 && !visited[y][x-1]){
      //push into queue
      q_push(x-1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x-1] = true;
	  if(fp_x == -1){
		fp_x = x-1;
		fp_y = y;
	  }
    }
    if(x+1 >= 0 && y >= 0 && x+1 < col && y < row && map[y][x+1] != -1 && !visited[y][x+1]){
      //push into queue
      q_push(x+1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x+1] = true;
      if(fp_x == -1){
        fp_x = x + 1;
        fp_y = y;
      }
    }
    if(x >= 0 && y-1 >= 0 && x < col && y-1 < row && map[y-1][x] != -1 && !visited[y-1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y-1, q_y);
      q_end++;
      visited[y-1][x] = true;
        if(fp_x == -1){
          fp_x = x;
          fp_y = y - 1;
        }
    }
    if(x >= 0 && y+1 >= 0 && x < col && y+1 < row && map[y+1][x] != -1 && !visited[y+1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y+1, q_y);
      q_end++;
      visited[y+1][x] = true;
      if(fp_x == -1){
        fp_x = x;
        fp_y = y + 1;
      }
    }
    //don't be too hury to pop new value
    //after visit all these "4" points, we should judge whether I should enter next depth
    //bad pos:bool whether_next = (x != fp_x && y != fp_y) ? false: true;
    printf("fp_x:%d,fp_y:%d\n\n",fp_x,fp_y);//debug
    print_q(q_x,q_y);//debug
    int next_x = q_pop(q_x);
    int next_y = q_pop(q_y);
    q_start++;
    printf("next_x:%d,next_y:%d\n",next_x, next_y);
    print_q(q_x,q_y);//debug
    bool whether_next;
    if(next_x != fp_x || next_y != fp_y)
      whether_next = false;
    else
      whether_next = true;
    if(next_x != -1 && next_y != -1){
      if(!whether_next)
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited, false);
      else
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited, true);
    }
    printf("leave bfs\n");
  }
}
//debug
void print_vis(bool vis[][col]){
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      if(vis[i][j])
        printf("1 ");
      else
        printf("0 ");
    }
    printf("\n");
  }
  printf("\n");
}

int main(int argc, char *argv[]){
  scanf("%d %d",&row, &col);
  //0: pathable
  //-1: handicap
  //-2: start
  //-3: end
  int x_start, y_start;//the start point
  int map[row][col];
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      scanf("%d", &map[i][j]);
      if(map[i][j] == -2){
        x_start = j;
        y_start = i;
      }
    }
  }
  bool visited[row][col];
  for(int i = 0; i < row; i++){
    for(int  j = 0; j < col; j++){
        visited[i][j] = false;
    }
  }
  int depth = 0;
  int max_size = 1;//max_size of queue
  for(int i = (row + col); i >= (col+1); i--){
    max_size *= i;
  }
  for(int i = 1; i <= row; i++){
    max_size /= i;
  }
  //now max_size is C(row+col,row):max way
  max_size *= (row+col);//max_step:walk a diagonal
  int q_x[max_size];
  int q_y[max_size];
  for(int i = 0; i < max_size ; i++){
    q_x[i] = -1;
    q_y[i] = -1;
  }
  visited[y_start][x_start] = true;
  bfs(map, x_start, y_start, depth, q_x, q_y, visited, true);
  return 0;
}
```
# 舊code
```c
#include<stdio.h>
#include<stdbool.h>
int q_start = 0, q_end = 0/*the index of last value +1*/;
int row, col;
void q_push(int val, int q[]){
  if(q_start <= q_end){
    q[q_end] = val;
  }
  else{
    printf("buffer saturated during push\n");
  }
}

int q_pop(int q[]){
  if(q_start <= q_end){
    return q[q_start];
  }
  else{
    printf("buffer saturated during pop %d\n",q_start);
    return -1;
  }
}

int bfs(int map[][col], int x, int y, int depth, int q_x[], int q_y[], bool visited[][col]){
  if(map[y][x] == -3){//end condition
    printf("%d\n",depth);
    return -1;//pop out this function
  }
  else{
    //put the next level value into queue then pop
    //push if pathable and in range and not visited
    int fp_x = -1;//first push x
    int fp_y = -1;
    if(x-1 >= 0 && y >= 0 && x-1 < col && y < row && map[y][x-1] != -1 && !visited[y][x-1]){
      //push into queue
      q_push(x-1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x-1] = true;
      fp_x = x-1;
      fp_y = y;
    }
    if(x+1 >= 0 && y >= 0 && x+1 < col && y < row && map[y][x+1] != -1 && !visited[y][x+1]){
      //push into queue
      q_push(x+1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x+1] = true;
      if(fp_x == -1){
        fp_x = x + 1;
        fp_y = y;
      }
    }
    if(x >= 0 && y-1 >= 0 && x < col && y-1 < row && map[y-1][x] != -1 && !visited[y-1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y-1, q_y);
      q_end++;
      visited[y-1][x] = true;
        if(fp_x == -1){
          fp_x = x;
          fp_y = y - 1;
        }
    }
    if(x >= 0 && y+1 >= 0 && x < col && y+1 < row && map[y+1][x] != -1 && !visited[y+1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y+1, q_y);
      q_end++;
      visited[y+1][x] = true;
      if(fp_x == -1){
        fp_x = x;
        fp_y = y + 1;
      }
    }
    int next_x = q_pop(q_x);
    int next_y = q_pop(q_y);
    q_start++;
    if(next_x != -1 && next_y != -1){
      if(next_x != fp_x && next_y != fp_y)
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited);
      else
        return bfs(map, next_x, next_y, depth+1, q_x, q_y, visited);
    }
  }
}


int main(int argc, char *argv[]){
  scanf("%d %d",&row, &col);
  //0: pathable
  //-1: handicap
  //-2: start
  //-3: end
  int x_start, y_start;//the start point
  int map[row][col];
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      scanf("%d", &map[i][j]);
      if(map[i][j] == -2){
        x_start = j;
        y_start = i;
      }
    }
  }
  bool visited[row][col];
  for(int i = 0; i < row; i++){
    for(int  j = 0; j < col; j++){
        visited[i][j] = false;
    }
  }
  int depth = 0;
  int max_size = 1;//max_size of queue
  for(int i = (row + col); i >= (col+1); i--){
    max_size *= i;
  }
  for(int i = 1; i <= row; i++){
    max_size /= i;
  }
  //now max_size is C(row+col,row):max way
  max_size *= (row+col);//max_step:walk a diagonal
  int q_x[max_size];
  int q_y[max_size];
  for(int i = 0; i < max_size ; i++){
    q_x[i] = -1;
    q_y[i] = -1;
  }
  visited[y_start][x_start] = true;
  bfs(map, x_start, y_start, depth, q_x, q_y, visited);
  return 0;
}

```

## with debug statement
```c
#include<stdio.h>
#include<stdbool.h>
int q_start = 0, q_end = 0/*the index of last value +1*/;
int row, col;
void q_push(int val, int q[]){
  if(q_start <= q_end){
    q[q_end] = val;
  }
  else{
    printf("buffer saturated during push\n");
  }
}

int q_pop(int q[]){
  if(q_start <= q_end){
    return q[q_start];
  }
  else{
    printf("buffer saturated during pop %d\n",q_start);
    return -1;
  }
}
//debug
void print_vis(bool vis[][col]){
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      if(vis[i][j])
        printf("1 ");
      else
        printf("0 ");
    }
    printf("\n");
  }
  printf("\n");
}
int bfs(int map[][col], int x, int y, int depth, int q_x[], int q_y[], bool visited[][col]){
  //debug
  printf("call bfs(x:%d,y:%d,dep:%d)\n", x, y, depth);
  //debug
  if(map[y][x] == -3){//end condition
    printf("%d\n",depth);
    return -1;//pop out this function
  }
  else{
    //put the next level value into queue then pop
    //push if pathable and in range and not visited
    int fp_x = -1;//first push x
    int fp_y = -1;
    if(x-1 >= 0 && y >= 0 && x-1 < col && y < row && map[y][x-1] != -1 && !visited[y][x-1]){
      //push into queue
      q_push(x-1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x-1] = true;
      fp_x = x-1;
      fp_y = y;
      print_vis(visited);//debug
    }
    if(x+1 >= 0 && y >= 0 && x+1 < col && y < row && map[y][x+1] != -1 && !visited[y][x+1]){
      //push into queue
      q_push(x+1, q_x);
      q_push(y, q_y);
      q_end++;
      visited[y][x+1] = true;
      if(fp_x == -1){
        fp_x = x + 1;
        fp_y = y;
      }
      print_vis(visited);//debug
    }
    if(x >= 0 && y-1 >= 0 && x < col && y-1 < row && map[y-1][x] != -1 && !visited[y-1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y-1, q_y);
      q_end++;
      visited[y-1][x] = true;
        if(fp_x == -1){
          fp_x = x;
          fp_y = y - 1;
        }
      print_vis(visited);//debug
    }
    if(x >= 0 && y+1 >= 0 && x < col && y+1 < row && map[y+1][x] != -1 && !visited[y+1][x]){
      //push into queue
      q_push(x, q_x);
      q_push(y+1, q_y);
      q_end++;
      visited[y+1][x] = true;
      if(fp_x == -1){
        fp_x = x;
        fp_y = y + 1;
      }
      print_vis(visited);//debug
    }
    //debug
    /*
    printf("q_start = %d\n",q_start);
    printf("q_end = %d\n",q_end);
    for(int i = 0; i < row*col; i++){
        printf("i: %d ",i);
        printf("%d,",q_x[i]);
        printf("%d \n",q_y[i]);
    }
    */
    //debug

    int next_x = q_pop(q_x);
    int next_y = q_pop(q_y);
    q_start++;
    if(next_x != -1 && next_y != -1){
      if(next_x != fp_x && next_y != fp_y)
        return bfs(map, next_x, next_y, depth, q_x, q_y, visited);
      else
        return bfs(map, next_x, next_y, depth+1, q_x, q_y, visited);
    }
    printf("leave bfs\n");
  }
}


int main(int argc, char *argv[]){
  scanf("%d %d",&row, &col);
  //0: pathable
  //-1: handicap
  //-2: start
  //-3: end
  int x_start, y_start;//the start point
  int map[row][col];
  for(int i = 0; i < row; i++){
    for(int j = 0; j < col; j++){
      scanf("%d", &map[i][j]);
      if(map[i][j] == -2){
        x_start = j;
        y_start = i;
      }
    }
  }
  //debug
  printf("x_start = %d\n", x_start);
  printf("y_start = %d\n", y_start);
  //debug
  bool visited[row][col];
  for(int i = 0; i < row; i++){
    for(int  j = 0; j < col; j++){
        visited[i][j] = false;
    }
  }
  int depth = 0;
  for(int i = (row + col); i >= (col+1); i--){
    max_size *= i;
  }
  for(int i = 1; i <= row; i++){
    max_size /= i;
  }
  //now max_size is C(row+col,row):max way
  max_size *= (row+col)/*max_step:walk a diagonal*/;
  int q_x[max_size];
  int q_y[max_size];
  visited[y_start][x_start] = true;
  bfs(map, x_start, y_start, depth, q_x, q_y, visited);//parameters?
  return 0;
}

```