给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思:
'#': 任何时候玩家都不能移动到此方格;
'+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;
'|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;
'.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;
'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。
此外,玩家不能移动出地图。
请找出满足下面两个性质的方格个数:
1. 玩家可以从初始位置移动到此方格;
2. 玩家不可以从此方格移动到目标位置。
输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。
接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'。
5 5
--+-+
..|#.
..|##
S-+-T
####.
如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示:
--+-+
..|#X
..|##
S-+-T
####X
该代码得分八十,剩下二十分不知道错在哪里。(再下面有AC代码)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 3000
typedef struct node{
int x;
int y;
char situation;
} node;
typedef struct queue{
node array[SIZE];
int head;
int rear;
int count;
} queue;
void enqueue(queue* ptr, node move);
node dequeue(queue* ptr);
bool isempty(queue* ptr);
void mark_footstep(node start, int** matrix);
bool isstuck(node start);
char** maze;
int r, c;
node destination;
int main(int argc, const char * argv[]) {
int i, j, count = 0;
int** matrix;
node start, temp;
scanf("%d %d", &r, &c);
maze = (char**)calloc(r, sizeof(char*));
matrix = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
maze[i] = (char*)calloc(c, sizeof(char));
matrix[i] = (int*)calloc(c, sizeof(int));
}
for(i = 0; i < r; i++){
getchar();
for(j = 0; j < c; j++){
maze[i][j] = getchar();
if(maze[i][j] == 'S'){
start.x = i;
start.y = j;
start.situation = 'S';
}
else if(maze[i][j] == 'T'){
destination.x = i;
destination.y = j;
destination.situation = 'T';
}
}
}
if(isstuck(start)){
puts("I'm stuck!");
}
else{
mark_footstep(start, matrix);
matrix[start.x][start.y] = 0;
matrix[destination.x][destination.y] = 0;
for(i = 0; i < r; i++){
for(j = 0; j < c; j++){
if(matrix[i][j]){
temp.x = i;
temp.y = j;
temp.situation = maze[i][j];
if(isstuck(temp)){
count++;
}
}
}
}
printf("%d\n", count);
}
for(i = 0; i < r; i++){
free(maze[i]);
free(matrix[i]);
}
free(maze);
free(matrix);
return 0;
}
void enqueue(queue* ptr, node move){
ptr->array[ptr->rear] = move;
ptr->rear = (ptr->rear + 1) % SIZE;
(ptr->count)++;
}
node dequeue(queue* ptr){
node temp = ptr->array[ptr->head];
ptr->head = (ptr->head + 1) % SIZE;
(ptr->count)--;
return temp;
}
bool isempty(queue* ptr){
if(!(ptr->count)){
return true;
}
else{
return false;
}
}
void mark_footstep(node start, int** matrix){
char situation;
node temp = start, next;
queue* q = (queue*)calloc(1, sizeof(queue));
int i, x, y;
int** visited = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
visited[i] = (int*)calloc(c, sizeof(int));
}
enqueue(q, temp);
while(!isempty(q)){
temp = dequeue(q);
visited[temp.x][temp.y] = matrix[temp.x][temp.y] = 1;
x = temp.x;
y = temp.y;
if(temp.situation == 'S' || temp.situation == '+' || temp.situation == 'T'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
}
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '-'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '|'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '.'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
}
for(i = 0; i < r; i++){
free(visited[i]);
}
free(visited);
}
bool isstuck(node start){
node temp = start, next;
char situation;
int i, x, y;
queue* q = (queue*)calloc(1, sizeof(queue));
int** visited = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
visited[i] = (int*)calloc(c, sizeof(int));
}
enqueue(q, temp);
while(!isempty(q)){
temp = dequeue(q);
visited[temp.x][temp.y] = 1;
x = temp.x;
y = temp.y;
if(temp.situation == 'T'){
return false;
}
else if(temp.situation == 'S' || temp.situation == '+'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
}
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '-'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '|'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
else if(temp.situation == '.'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
}
}
}
for(i = 0; i < r; i++){
free(visited[i]);
}
free(visited);
free(q);
return true;
}
下面是AC代码。上面的代码算法没有错误,只是在广度优先搜索的时候错误地在出队的时候标记该点已访问。实际上,深度优先搜索时一定要在入队时就把该点标记为已访问,否则可能会把一个点重复入队。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 3000
typedef struct node{
int x;
int y;
char situation;
} node;
typedef struct queue{
node array[SIZE];
int head;
int rear;
int count;
} queue;
void enqueue(queue* ptr, node move);
node dequeue(queue* ptr);
bool isempty(queue* ptr);
void mark_footstep(node start, int** matrix);
bool isstuck(node start);
char** maze;
int r, c;
node destination;
int main(int argc, const char * argv[]) {
int i, j, count = 0;
int** matrix;
node start, temp;
scanf("%d %d", &r, &c);
maze = (char**)calloc(r, sizeof(char*));
matrix = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
maze[i] = (char*)calloc(c, sizeof(char));
matrix[i] = (int*)calloc(c, sizeof(int));
}
for(i = 0; i < r; i++){
getchar();
for(j = 0; j < c; j++){
maze[i][j] = getchar();
if(maze[i][j] == 'S'){
start.x = i;
start.y = j;
start.situation = 'S';
}
else if(maze[i][j] == 'T'){
destination.x = i;
destination.y = j;
destination.situation = 'T';
}
}
}
if(isstuck(start)){
puts("I'm stuck!");
}
else{
mark_footstep(start, matrix);
matrix[start.x][start.y] = 0;
matrix[destination.x][destination.y] = 0;
for(i = 0; i < r; i++){
for(j = 0; j < c; j++){
if(matrix[i][j]){
temp.x = i;
temp.y = j;
temp.situation = maze[i][j];
if(isstuck(temp)){
count++;
}
}
}
}
printf("%d\n", count);
}
for(i = 0; i < r; i++){
free(maze[i]);
free(matrix[i]);
}
free(maze);
free(matrix);
return 0;
}
void enqueue(queue* ptr, node move){
ptr->array[ptr->rear] = move;
ptr->rear = (ptr->rear + 1) % SIZE;
(ptr->count)++;
}
node dequeue(queue* ptr){
node temp = ptr->array[ptr->head];
ptr->head = (ptr->head + 1) % SIZE;
(ptr->count)--;
return temp;
}
bool isempty(queue* ptr){
if(!(ptr->count)){
return true;
}
else{
return false;
}
}
void mark_footstep(node start, int** matrix){
char situation;
node temp = start, next;
queue* q = (queue*)calloc(1, sizeof(queue));
int i, x, y;
int** visited = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
visited[i] = (int*)calloc(c, sizeof(int));
}
enqueue(q, temp);
while(!isempty(q)){
temp = dequeue(q);
visited[temp.x][temp.y] = matrix[temp.x][temp.y] = 1;
x = temp.x;
y = temp.y;
if(temp.situation == 'S' || temp.situation == '+' || temp.situation == 'T'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
}
else if(temp.situation == '-'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
}
else if(temp.situation == '|'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
}
else if(temp.situation == '.'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = matrix[next.x][next.y] = 1;
}
}
}
for(i = 0; i < r; i++){
free(visited[i]);
}
free(visited);
}
bool isstuck(node start){
node temp = start, next;
char situation;
int i, x, y;
queue* q = (queue*)calloc(1, sizeof(queue));
int** visited = (int**)calloc(r, sizeof(int*));
for(i = 0; i < r; i++){
visited[i] = (int*)calloc(c, sizeof(int));
}
enqueue(q, temp);
visited[temp.x][temp.y] = 1;
while(!isempty(q)){
temp = dequeue(q);
x = temp.x;
y = temp.y;
if(temp.situation == 'T'){
return false;
}
else if(temp.situation == 'S' || temp.situation == '+'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
}
else if(temp.situation == '-'){
if(y + 1 < c && (situation = maze[x][y + 1]) != '#' && !visited[x][y + 1]){
next.x = x;
next.y = y + 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
if(y - 1 >= 0 && (situation = maze[x][y - 1]) != '#' && !visited[x][y - 1]){
next.x = x;
next.y = y - 1;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
}
else if(temp.situation == '|'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
if(x - 1 >= 0 && (situation = maze[x - 1][y]) != '#' && !visited[x - 1][y]){
next.x = x - 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
}
else if(temp.situation == '.'){
if(x + 1 < r && (situation = maze[x + 1][y]) != '#' && !visited[x + 1][y]){
next.x = x + 1;
next.y = y;
next.situation = situation;
enqueue(q, next);
visited[next.x][next.y] = 1;
}
}
}
for(i = 0; i < r; i++){
free(visited[i]);
}
free(visited);
free(q);
return true;
}