#P1089. 测-机甲大师的裁判系统
测-机甲大师的裁判系统
题目描述
背景
在RoboMaster比赛中,需要使用裁判系统进行自动化的比赛裁判,通过各机器人上安装的传感器来计算机器人的血量等信息,现在需要你编写一个简化的裁判系统,实现部分裁判系统的功能。
实现
裁判系统从标准输入接受各机器人回传的数据,数据格式如下
时间 命令字 [参数1] [参数2] [参数3]
时间为0~65535整数,单位为s
具体指令如下

输入的所有参数范围均为,等级输入范围为,映射为1,2,3级步兵。
每个机器人具有以下属性

【上述表格存在错误!!!,所属队伍范围为0~65535整数】
机器人枪口热量会随时间降低,每秒钟降低1点热量,当机器人热量大于热量上限时每秒钟每1点超出的热量都将造成1点伤害,先结算热量伤害再结算新的热量
不同等级和类型机器人属性值对应如下
(为简化题目仅有步兵和工程两种机器人,且工程无法升级)

裁判系统向标准输出输出机器人被击毁信息,格式如下
D [死亡时刻] [所属队伍] [机器人标识符]
具体过程
应该建立一个机器人存储池,将机器人分为正常和被击毁两类
每个时间刻的处理顺序:先计算机器人是否超热量,机器人因超热量被扣除血量,判断机器人是否被击毁并输出,然后接收命令字和参数表,处理命令。
如果命令字为A,则查找被击毁机器人中是否存在相同所属队伍和标识符的机器人,如果存在且兵种相符则将其移至正常机器人列表,并将血量设置为血量上限,热量设置为0,如果存在但兵种不相符,不执行任何操作;如果没能找到机器人,则在正常机器人列表中查询,若找到,则不执行任何操作,处理结束,若未找到则新建一个机器人信息,等级为1级,将血量设置为血量上限,热量设置为0,加入到正常机器人列表。
如果命令字为F,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则保存其目前血量。
如果命令字为H,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则判断其是否为步兵,若不是,则处理结束,若是,则保存其当前热量。
如果命令字为U,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则判断其是否为步兵且目标等级大于当前等级,若不是,则处理结束,若是,修改其血量及热量上限,将其血量重置为血量上限。 注意:在计算过程中出现小数一律向下取整
测试点范围
对于的数据,所接收命令数,只出现步兵机器人,所有机器人均不出现超热量情况;
对于的数据,所接收命令数,所有机器人均不出现超热量情况;
对于的数据,所接收命令数
对于的数据,所接收命令数,时间
输入格式
N
时间 命令字 [参数1] [参数2] [参数3]
时间 命令字 [参数1] [参数2] [参数3]
…………
时间 命令字 [参数1] [参数2] [参数3]
保证时间$t_n \leqslant t_{n+1}$
输出格式
D [所属队伍] [机器人标识符]
D [所属队伍] [机器人标识符]
…………
D [所属队伍] [机器人标识符]
代码
考虑到此题较难,我们提供部分代码
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))
// List
typedef void (*DeleteFunction)(void*);
struct DataNode {
DeleteFunction delete_function;
void* data;
struct DataNode* next;
struct DataNode* prev;
};
typedef struct DataNode* List;
typedef struct DataNode* Node;
List create_list() {
List head = malloc(sizeof(struct DataNode));
head->next = head;
head->prev = head;
head->data = NULL;
head->delete_function = NULL;
return head;
}
int is_empty(List head) {
return head->next == head;
}
void delete_node(List head, Node node) {
if (node == head || is_empty(head)) {
return;
}
node->prev->next = node->next;
node->next->prev = node->prev;
if (node->delete_function != NULL) {
node->delete_function(node->data);
}
free(node);
node = NULL;
}
void pop_back(List head) {
if (is_empty(head)) {
return;
}
Node back = head->prev;
delete_node(head, back);
}
void clear_list(List head) {
while (!is_empty(head)) {
pop_back(head);
}
}
void free_list(List head) {
clear_list(head);
free(head);
}
void push_back(List head, void* data, DeleteFunction delete_function) {
Node node = malloc(sizeof(struct DataNode));
node->data = data;
node->delete_function = delete_function;
Node back = head->prev;
back->next = node;
node->prev = back;
node->next = head;
head->prev = node;
}
Node find_node(List head, void* data, int (*equal)(void*, void*)) {
Node current = head->next;
while (current != head) {
if (equal(current->data, data)) {
return current;
}
current = current->next;
}
return NULL;
}
typedef int (*ProcessFunction)(Node node);
void for_each_node(List head, ProcessFunction function) {
Node current = head->next;
while (current != head) {
Node next = current->next;
if (!function(current)) {
delete_node(head, current);
}
current = next;
}
}
// Robot
enum RobotType {
STANDARD,
ENGINEER,
ROBOT_TYPE_LENGTH,
};
struct RobotData {
int hp_max;
int heat_max;
int hp;
int heat;
int team;
int id;
int level;
enum RobotType type;
};
typedef struct RobotData* Robot;
// Judgement
int time_counter = 0;
List alive_robots;
List dead_robots;
int max_hp[ROBOT_TYPE_LENGTH][4] = {
{0, 100, 150, 250},
{0, 300, 300, 300}
};
int max_heat[ROBOT_TYPE_LENGTH][4] = {
{0, 100, 200, 300},
{0, 0, 0, 0}
};
int heat_process(Node node);
int death_process(Node node);
void add_robot(int team, int id, enum RobotType robot_type);
void fight_robot(int team, int id, int damage);
void heat_robot(int team, int id, int heat);
void upgrade_robot(int team, int id, int level);
int command_time = 0;
int n;
void tick() {
for_each_node(alive_robots, heat_process);
for_each_node(alive_robots, death_process);
while (command_time == time_counter) {
char op;
int p1, p2, p3;
scanf("%c %d %d %d", &op, &p1, &p2, &p3);
switch (op) {
case 'A':
add_robot(p1, p2, p3);
break;
case 'F':
fight_robot(p1, p2, p3);
break;
case 'H':
heat_robot(p1, p2, p3);
break;
case 'U':
upgrade_robot(p1, p2, p3);
break;
}
if (n > 0) {
scanf("%d ", &command_time);
n--;
}
else {
command_time = 65536;
}
}
time_counter++;
}
int main(void) {
alive_robots = create_list();
dead_robots = create_list();
scanf("%d", &n);
n--;
scanf("%d ", &command_time);
for (int i = 0; i < 65536; i++) {
tick();
}
free_list(alive_robots);
free_list(dead_robots);
return 0;
}
// 你的代码会放在这里
你需要补充这些函数:
// 处理机器人的热量
int heat_process(Node node);
// 检查机器人是否因过热死亡
int death_process(Node node);
// 向指定队伍添加新机器人
void add_robot(int team, int id, enum RobotType robot_type);
// 对指定机器人造成伤害
void fight_robot(int team, int id, int damage);
// 对指定机器人增加热量
void heat_robot(int team, int id, int heat);
// 将指定机器人升级
void upgrade_robot(int team, int id, int level);
7
15 A 37954 46652 1
241 A 37954 32054 1
341 A 19899 48958 1
356 U 37954 32054 1
388 U 37954 46652 3
398 F 37954 46652 148
461 F 37954 32054 448
D 37954 32054
11
0 A 9741 59525 1
38 A 4047 59111 0
53 A 24690 44013 1
102 A 24690 26218 0
151 A 15513 50055 1
210 F 4047 59111 429
306 F 15513 50055 474
371 U 4047 59111 1
441 A 15513 50055 1
495 F 4047 59111 372
583 F 15513 50055 372
D 4047 59111
D 15513 50055
D 15513 50055
10
0 A 45111 32727 0
26 A 20852 55902 1
46 A 57677 45042 0
55 A 62510 3725 0
66 A 20852 28441 1
73 U 57677 45042 2
80 H 62510 3725 492
176 F 20852 55902 302
194 F 20852 28441 121
196 H 20852 55902 54
D 62510 3725
D 20852 55902
提示
无
相关
在下列比赛中: