#P1089. 测-机甲大师的裁判系统

测-机甲大师的裁判系统

题目描述

背景

在RoboMaster比赛中,需要使用裁判系统进行自动化的比赛裁判,通过各机器人上安装的传感器来计算机器人的血量等信息,现在需要你编写一个简化的裁判系统,实现部分裁判系统的功能。

实现

裁判系统从标准输入接受各机器人回传的数据,数据格式如下

时间 命令字 [参数1] [参数2] [参数3]

时间为0~65535整数,单位为s

具体指令如下

输入的所有参数范围均为[0,65535][0, 65535],等级输入范围为[1,3][1, 3],映射为1,2,3级步兵。

每个机器人具有以下属性

【上述表格存在错误!!!,所属队伍范围为0~65535整数】

机器人枪口热量会随时间降低,每秒钟降低1点热量,当机器人热量大于热量上限时每秒钟每1点超出的热量都将造成1点伤害,先结算热量伤害再结算新的热量

不同等级和类型机器人属性值对应如下

(为简化题目仅有步兵和工程两种机器人,且工程无法升级)

裁判系统向标准输出输出机器人被击毁信息,格式如下

D [死亡时刻] [所属队伍] [机器人标识符]

具体过程

应该建立一个机器人存储池,将机器人分为正常和被击毁两类

每个时间刻的处理顺序:先计算机器人是否超热量,机器人因超热量被扣除血量,判断机器人是否被击毁并输出,然后接收命令字和参数表,处理命令。

如果命令字为A,则查找被击毁机器人中是否存在相同所属队伍和标识符的机器人,如果存在且兵种相符则将其移至正常机器人列表,并将血量设置为血量上限,热量设置为0,如果存在但兵种不相符,不执行任何操作;如果没能找到机器人,则在正常机器人列表中查询,若找到,则不执行任何操作,处理结束,若未找到则新建一个机器人信息,等级为1级,将血量设置为血量上限,热量设置为0,加入到正常机器人列表。

如果命令字为F,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则保存其目前血量。

如果命令字为H,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则判断其是否为步兵,若不是,则处理结束,若是,则保存其当前热量。

如果命令字为U,则在正常机器人列表中查找该机器人,若未找到,则处理结束,若找到则判断其是否为步兵且目标等级大于当前等级,若不是,则处理结束,若是,修改其血量及热量上限,将其血量重置为血量上限。 注意:在计算过程中出现小数一律向下取整

测试点范围

对于20%20\%的数据,所接收命令数N200N\leqslant 200,只出现步兵机器人,所有机器人均不出现超热量情况;

对于50%50\%的数据,所接收命令数N65535N\leqslant 65535,所有机器人均不出现超热量情况;

对于70%70\%的数据,所接收命令数N65535N\leqslant 65535

对于100%100\%的数据,所接收命令数N109N\leqslant 10^9,时间t[0,65535]t \in [0, 65535]

输入格式

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

提示