# 找路 :::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; } ```