列表

详情


SH15. 找到最近的NPC

描述

在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)

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 352KB, 提交时间: 2021-07-16

#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) {
  
  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);
}

C 解法, 执行用时: 2ms, 内存消耗: 352KB, 提交时间: 2020-05-20

#include<stdio.h>
#include<math.h>
int main(void)
{
    int x, y, n, a, b, c, d;
    double num, t = 128*128*2;
    scanf("%d,%d,%d", &x, &y, &n);
    for(int i=0; i<n; i++)
    {
        scanf(",%d,%d", &a, &b);
        num = pow(a-x,2) + pow(b-y,2);
        if(t > num)
        {
            t = num;
            c = a;
            d = b;
        }
    }
    printf("(%d,%d)", c, d);
    return 0;
}

上一题