3 Star 0 Fork 0

xjl12/2023华为软件精英挑战赛

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
main.cpp 10.66 KB
一键复制 编辑 原始数据 按行查看 历史
xjl12 提交于 2023-04-01 17:23 . All done
#include "dat.h"
#include "xjl_greedy.h" // 启用【肖氏排序】算法
// #include "time_greedy.h" // 启用【最近距离贪心】算法
// #include "simple_choose.h" // 启用【简单选择】算法
#include "time_frac_greedy.h"
// #include "gain_greedy.h"
char line[1024];
int getGain(int origin_gain, int time)
{
if (time >= 9000)
return 0.8 * origin_gain;
double t = 1.0 - origin_gain / 9000.0;
double r = 1.0 - sqrt(1.0 - t * t);
r = r * 0.2 + 0.8;
return origin_gain * r;
}
bool assainTaskForRobot(Robot &cur_robot)
{
if (workben_cnt == 43)
return assainTaskForRobotMap1(cur_robot);
else if (workben_cnt == 50)
return assainTaskForRobotMap3(cur_robot);
else if (workben_cnt == 18)
return assainTaskForRobotMap4(cur_robot);
else
return assainTaskForRobotMap2(cur_robot);
}
void readMapData()
{
int robot_id = 0;
for (int i = 0; i <= 100; i++)
{
fgets(line, sizeof line, stdin);
if (line[0] == 'O' && line[1] == 'K')
break;
for (int j = 0; j < 100; j++)
{
if (line[j] != '.')
{
Location curloc = {j * 50 + 25, 4975 - i * 50};
if (line[j] == 'A')
{
robot_list[robot_id].robo_id = robot_id;
robot_list[robot_id++].loc = curloc;
}
else
{
line[j] -= '0';
workbench_list[workben_cnt].loc = curloc;
workbench_list[workben_cnt].remain_time = init_remain_time[line[j]];
workbenches_in_type[line[j]].push_back(workben_cnt);
workbench_list[workben_cnt++].type = line[j];
}
}
}
}
for (int i = 1; i < 8; i++)
{
for (auto start_work_id : workbenches_in_type[i])
{
for (int j = 1; j <= init_action_workbench_end[i][0]; j++)
{
for (auto end_work_id : workbenches_in_type[init_action_workbench_end[i][j]])
{
SingleAction tmp = {start_work_id, end_work_id,
i,
init_action_bar[i],
init_action_sell[i],
calculateTimeBetweenLoc(workbench_list[start_work_id].loc, workbench_list[end_work_id].loc)};
tmp.gain = getGain(tmp.sell - tmp.bar, tmp.time);
actions.push_back(tmp);
}
}
}
}
for (auto &rob : robot_list)
{
rob.action_status = 0;
rob.expect_loc.x = -1;
rob.collision_frame = -1;
}
for (auto &rob : robot_list)
{
if (assainTaskForRobot(rob))
{
rob.action_status = 1;
rob.expect_loc = workbench_list[rob.cur_action->workbench_start].loc;
}
}
}
void findSecondaryWorkbench(Robot &rob)
{
// 仅地图1启用
if (workben_cnt == 43)
{
rob.expect_loc = map_one_expected_loc[rob.robo_id];
}
}
// 为卖不出东西的机器人重新分配任务
bool reAssainTaskInSecondStage(Robot &r)
{
action_iterator best = actions.end();
int shortest_time = INT_MAX;
for (auto it = actions.begin(); it < actions.end(); it++)
{
if (it->load_type != r.load_type)
continue;
Workbench &work_end = workbench_list[it->workbench_end];
if (work_end.hasMaterialIn(r.load_type))
continue;
if (judgeActionConflict(it, r.loc))
{
int t = calculateTimeBetweenLoc(r.loc, work_end.loc);
if (shortest_time > t)
{
best = it;
shortest_time = t;
}
}
}
if (best == actions.end())
return false;
r.action_status = 2;
r.cur_action = best;
r.expect_loc = workbench_list[best->workbench_end].loc;
return true;
}
void afterSell(Workbench &w, int load_type)
{
w.raw_material_status |= 1 << load_type;
if (w.getCurRawMaterialsNum() == init_material_counts[w.type] && w.remain_time == -1 || w.type > 7)
{
w.raw_material_status = 0;
w.remain_time = total_produce_time[w.type];
}
}
double antiCollisionAngle(double ang)
{
double ans = ang + PI / 4;
if (ans > PI)
ans -= PI2;
return ans;
}
void navigateRobot(int robo_id)
{
Robot *rob_p = robot_list + robo_id;
if (rob_p->expect_loc.isValid() == false || rob_p->expect_loc == rob_p->loc)
{
if (rob_p->w > 0)
printf("rotate %d %f\n", robo_id, 0.0);
if (rob_p->speed.getSpeed() > 0)
printf("forward %d %f\n", robo_id, 0.0);
return;
}
double expect_angle = getAngleBetweenLoc(rob_p->loc, rob_p->expect_loc);
if (rob_p->collision_frame > 0)
{
if (rob_p->collision_frame > frameID)
expect_angle = antiCollisionAngle(expect_angle);
else
rob_p->collision_frame = -1;
}
else
{
for (int i = 0; i < 4; i++)
{
if (i == robo_id)
continue;
Robot *other_robot = robot_list + i;
SpeedVector a = rob_p->speed, b = other_robot->speed;
if (a.getSpeed() > COLLISION_EPS && b.getSpeed() > COLLISION_EPS)
{
if ((a / a.getSpeed() + b / b.getSpeed()).getSpeed() < COLLISION_EPS) // 反向
{
Location d = rob_p->loc - other_robot->loc;
SpeedVector dv = {(double)d.x, (double)d.y};
if ((dv / dv.getSpeed() + a / a.getSpeed()).getSpeed() < COLLISION_EPS)
{
expect_angle = antiCollisionAngle(expect_angle);
rob_p->collision_frame = frameID + COLLISION_DETECTION_LIMIT;
}
}
}
else if (workben_cnt != 43 && calculateTimeBetweenLoc(rob_p->loc, other_robot->loc) < 30 && a.getSpeed() > COLLISION_EPS)
{
rob_p->collision_frame = frameID + COLLISION_DETECTION_LIMIT;
expect_angle = antiCollisionAngle(expect_angle);
// fprintf(stderr, "Collision detected for %d in frame %d\n", robo_id, frameID);
}
}
}
double rotate_dir = expect_angle > rob_p->face_angle ? 1.0 : -1.0;
double dangle = abs(expect_angle - rob_p->face_angle);
if (dangle > abs(rob_p->face_angle - expect_angle))
{
dangle = abs(rob_p->face_angle - expect_angle);
rotate_dir = -rotate_dir;
}
if (dangle > PI)
{
rotate_dir = -rotate_dir;
dangle = PI2 - dangle;
}
if (dangle > PI_DIV_2)
printf("forward %d %f\n", robo_id, 0.0);
else
printf("forward %d %f\n", robo_id, 6.0 * cos(dangle));
if (dangle > ANGLE_EPS)
printf("rotate %d %f\n", robo_id, rotate_dir * min(PI, dangle / 0.02));
else if (rob_p->w != 0)
printf("rotate %d %f\n", robo_id, 0.0);
}
void controlRobot(int robo_id)
{
Robot *rob_p = robot_list + robo_id;
if (rob_p->action_status == 0)
{
if (!assainTaskForRobot(robot_list[robo_id]))
{
// if (rob_p->expect_loc.isValid() == false)
// findSecondaryWorkbench(robot_list[robo_id]);
navigateRobot(robo_id);
return;
}
rob_p->action_status = 1;
rob_p->expect_loc = workbench_list[rob_p->cur_action->workbench_start].loc;
// fprintf(stderr, "After assain %d : %d -> %d, load type: %d, Raw Material Status:%d\n", robo_id, rob_p->cur_action->workbench_start, rob_p->cur_action->workbench_end, rob_p->cur_action->load_type, workbench_list[rob_p->cur_action->workbench_end].raw_material_status);
}
Workbench &workbench_end = workbench_list[rob_p->cur_action->workbench_end];
if (rob_p->cur_workbench_id >= 0)
{
Workbench &cur_workbench = workbench_list[rob_p->cur_workbench_id];
// 机器人到达售卖点
if (rob_p->cur_action->workbench_end == rob_p->cur_workbench_id && rob_p->action_status == 2 && cur_workbench.hasMaterialIn(rob_p->load_type) == false)
{
printf("sell %d\n", robo_id);
afterSell(cur_workbench, rob_p->load_type);
rob_p->load_type = 0;
rob_p->action_status = 0;
rob_p->expect_loc.x = -1;
return;
}
// 机器人到达购买点
if (rob_p->cur_action->workbench_start == rob_p->cur_workbench_id && rob_p->action_status == 1)
{
printf("buy %d\n", robo_id);
if (cur_workbench.remain_time != 0)
cur_workbench.output_status = 0;
rob_p->action_status = 2;
rob_p->expect_loc = workbench_end.loc;
}
}
if (rob_p->action_status == 2 && workbench_end.hasMaterialIn(rob_p->load_type))
{
// 假如机器人持有的物品无法卖出
int surplus_time = calculateTimeBetweenLoc(rob_p->loc, workbench_end.loc);
if (workbench_end.getCurRawMaterialsNum() < init_material_counts[workbench_end.type] || workbench_end.output_status == 1 || workbench_end.remain_time > surplus_time)
{
rob_p->action_status = 0;
if (!reAssainTaskInSecondStage(robot_list[robo_id]))
{
printf("destroy %d\n", robo_id);
fprintf(stderr, "Frame: %d\tRobo %d destroy material type %d\n", frameID, robo_id, rob_p->load_type);
}
}
}
navigateRobot(robo_id);
}
inline void readUntilOK()
{
int k, ignore;
double ignoref, x, y;
scanf("%d%d", &money, &k);
for (int i = 0; i < k; i++)
{
Workbench &cur_work = workbench_list[i];
scanf("%d%lf%lf%d%d%d", &ignore, &ignoref, &ignoref,
&cur_work.remain_time,
&cur_work.raw_material_status,
&cur_work.output_status);
}
for (int i = 0; i < 4; i++)
{
Robot &cur_rob = robot_list[i];
scanf("%d%d%lf%lf%lf%lf%lf%lf%lf%lf",
&cur_rob.cur_workbench_id,
&cur_rob.load_type,
&ignoref,
&ignoref,
&cur_rob.w,
&cur_rob.speed.x, &cur_rob.speed.y,
&cur_rob.face_angle,
&x, &y);
cur_rob.loc.x = round(x * 100);
cur_rob.loc.y = round(y * 100);
}
scanf("%s", line);
}
int main()
{
readMapData();
puts("OK");
fflush(stdout);
while (scanf("%d", &frameID) != EOF)
{
printf("%d\n", frameID);
readUntilOK();
for (int i = 0; i < 4; i++)
{
controlRobot(i);
}
puts("OK");
fflush(stdout);
}
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/xjl12/huawei_program_2023.git
git@gitee.com:xjl12/huawei_program_2023.git
xjl12
huawei_program_2023
2023华为软件精英挑战赛
traditional

搜索帮助