SH15. 找到最近的NPC
描述
在2D游戏的一张地图中随机分布着n个NPC,玩家君莫笑进入地图时随机出生在了一个坐标(x,y)。请找到距离玩家最近的NPC。假设地图大小为128*128,NPC和玩家均不能出现在地图外面。
输入描述
参数一:整形,玩家出生坐标x输出描述
查询到的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; }