您的位置:首页 > 其它

I’m stuck!

2016-04-04 11:47 387 查看
问题描述

给定一个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: