首页 > 试题广场 >

找到最近的NPC

[编程题]找到最近的NPC
  • 热度指数:1712 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

在2D游戏的一张地图中随机分布着nNPC,玩家君莫笑进入地图时随机出生在了一个坐标(x,y)。请找到距离玩家最近的NPC。假设地图大小为128*128,NPC和玩家均不能出现在地图外面。


输入描述:
参数一:整形,玩家出生坐标x

参数二:整形,玩家出生坐标y

参数三:整形,NPC数量n

参数四:NPC二维坐标数组的一维表示,使用字符串形式传入,注意逗号前后不要加空格,比如地图中有两个NPC,坐标分别是(32,33)和(25,25),则此处传入32,33,25,25


输出描述:
查询到的NPC坐标,注意坐标值前后有圆括号
示例1

输入

32,48,3,33,40,40,50,32,45

输出

(32,45)

备注:
NPC数量不超过1000个
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>

#define NOT !
#define NPC 2

typedef enum { UNKNOW = 0, OK = 1, ERROR = -1, MEMORY_OVERFLOW = -2 } Status;

typedef struct Coordinate {
  int x;
  int y;
} Coord;

// ==================== 链式队列存储结构表示与实现 ====================
typedef Coord QElemType;

typedef struct QNode {
  QElemType data;     // 链式队列节点的数据域
  struct QNode* next; // 链式队列节点的指针域
} QNode, *PQNode;

typedef struct {
  PQNode front; // 教材上front “始终” 指向头节点,而非首元节点
  PQNode rear;
  size_t length;
} LinkQueue;

Status InitQueue(LinkQueue* Q) {
  if (!((*Q).front = (PQNode) calloc(1, sizeof(QNode)))) { // may be no enough space!
    fprintf(stderr, "InitQueue Memory Overflow: %s\n", strerror(errno));
    exit(MEMORY_OVERFLOW);
  }
  (*Q).rear = (*Q).front;
  (*Q).length = 0;
  return OK;
}

bool QueueEmpty(LinkQueue* Q) {
  return (*Q).length == 0;
}

size_t QueueLength(LinkQueue* Q) {
  return (*Q).length;
}

Status EnQueue(LinkQueue* Q, QElemType e) {
  PQNode new_node = (PQNode) calloc(1, sizeof(QNode));
  if (!new_node) { // may be no enough space!
    fprintf(stderr, "EnQueue Memory Overflow: %s\n", strerror(errno));
    exit(MEMORY_OVERFLOW);
  }
  (*new_node).data = e;
  (*Q).rear = (*((*Q).rear)).next = new_node;
  ++(*Q).length;
  return OK;
}

Status DeQueue(LinkQueue* Q, QElemType* e) {
  if (QueueEmpty(Q)) {
    fputs("DeQueue ERROR: The Queue is empty!\n", stderr);
    return ERROR;
  }
  
  PQNode node_to_delete = (*(*Q).front).next;
  *e = (*node_to_delete).data;
  (*(*Q).front).next = (*node_to_delete).next;
  if (!(*(*Q).front).next)
    (*Q).rear = (*Q).front;
  
  free(node_to_delete);
  --(*Q).length;
  return OK;
}

QElemType GetFront(LinkQueue* Q) {
  if (QueueEmpty(Q)) {
    fputs("DeQueue ERROR: The Queue is empty!\n", stderr);
    return (Coord) {-1, -1};
  }
  return (*(*(*Q).front).next).data;
}

Status DestroyQueue(LinkQueue* Q) {
  PQNode p = (*Q).front, next;
  while (p) {
    next = (*p).next;
    free(p);
    p = next;
  }
  (*Q).front = (*Q).rear = NULL;
  return OK;
}
// ==================== 链式队列存储结构表示与实现 ====================

// ==================== memory static area ====================
const int N = 130; //  内存全局区,一般用来存放全局变量或静态变量
int board[N][N];
// ==================== memory static area ====================

// ==================== Function Prototype (函数原型区) ====================
void breadth_first_search_algorithm(const int sx, const int sy);
// ==================== Function Prototype ====================

int main(const int argc, const char* argv[]) {
  
  int x, y, n;
  fscanf(stdin, "%d,%d,%d", &y, &x, &n);
  
  int tx, ty;
  while (n--) {
    fscanf(stdin, ",%d,%d", &ty, &tx);
    *(*(board + ty) + tx) = NPC; // NPC
  }
  
  breadth_first_search_algorithm(x, y);
  return 0;
}

void breadth_first_search_algorithm(const int sx, const int sy) {
  
  usleep(900 * 1000);
  
  LinkQueue Q;
  InitQueue(&Q);
  EnQueue(&Q, (Coord) {.x = sx, .y = sy}); 
  *(*(board + sy) + sx) = 1; // mark as visited
  
  static const int dirs[] = { 0, -1, 0, 1, 0 }; // 存放在全局区
  
  Coord coord;
  int i, x, y, nx, ny;
  while (NOT QueueEmpty(&Q)) {
    DeQueue(&Q, &coord);
    x = coord.x, y = coord.y;
    for (i = 0; i < 4; ++i) {
      nx = x + *(dirs + i), ny = y + *(dirs + i + 1);
      if (nx < 0 || ny < 0 || nx == 127 || ny == 127 || *(*(board + ny) + nx) == 1)
        continue;
      if (*(*(board + ny) + nx) == NPC) { // 找到了解
        fprintf(stdout, "(%d,%d)", ny, nx);
        DestroyQueue(&Q); // 把堆内存还给操作系统
        return;
      }
      EnQueue(&Q, (Coord) {.x = nx, .y = ny});
      *(*(board + ny) + nx) = 1;
    }
  }
  
  DestroyQueue(&Q);
}

发表于 2021-07-16 10:57:49 回复(0)