I’m stuck!

问题描述

给定一个R行C列的地图,地图的每一个方格可能是'#''+''-''|''.''S''T'七个字符中的一个,分别表示如下意思:

'#': 任何时候玩家都不能移动到此方格;

'+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;

'-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;

'|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;

'.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;

'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;

'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。

此外,玩家不能移动出地图。

请找出满足下面两个性质的方格个数:

1. 玩家可以从初始位置移动到此方格;

2. 玩家可以从此方格移动到目标位置。

输入格式

输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。

接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'

输出格式
如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
样例输入

5 5

--+-+

..|#.

..|##

S-+-T

####.

样例输出
2
样例说明

如果把满足性质的方格在地图上用'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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值