当前位置: 首页 > news >正文

CSDN竞赛68期

CSDN竞赛68期

  • CSDN竞赛68期
    • 1.小球游戏
    • 2.王子闯闸门
      • 分析

CSDN竞赛68期

1.小球游戏

这个是64期的题目,完全一样,有点无语了,竟然又出了,真不知道怎么出的题。
参考:CSDN周赛64期

2.王子闯闸门

波斯王子要去救被贾法尔囚禁的公主,但贾法尔用黑魔法在他面前设置了编号从1到n的n道闸门。从王子的位置到1号闸门需要1秒,从n号闸门到公主所在的位置也需要1秒,从p号闸门到p+1或p-1号闸门都需要1秒。 每过1秒钟,王子都必须决定选择前进一道闸门、后退一道闸门或停在原地这三种动作中的一种。当然,王子不能选择移动到关闭状态的闸门而只能选择开启状态的闸门。在王子做出动作选择后,闸门也可能会有关闭和开启的动作,如果王子做完动作后,其所在的闸门在该秒内的动作是从开启变为关闭则他就会被闸门夹死。 现在给出闸门数量n和m个闸门的动作时刻表,求波斯王子需要多少秒才能救出公主。

分析

这道题逻辑很简单,在t时间时在p位置,那么有三个选择,如果t+1时p+1的门未关闭,则到p+1的位置,如果t+1时p+1的门会关闭,则再检查p位置在t+1时是否会关闭,如果不关,留在p位置;如果关闭,退到p-1的位置,如果p-1的位置也关闭,会死掉,这时说明进入p位置的时间不对,那么回退到在p-1位置的最后时间(进入到p位置的前一秒),这时不应该进入p位置,而是在p-1位置上多等1s(这可能不是最优解,但有可能避免挂掉的可能)。这就需要记住在每个位置上的时间。

在考试的时候,我按照上面的逻辑写出来了,但是会超时,因为每一秒都需要查询关闭时间表,而每次都要m次(因为有m个时刻表)。在考试结束后,想到的方法是优化查询时刻表。首先对时刻表根据门编号排序,然后用数组x[n+2][2]来记录每一个位置编号在时刻表中的起始和结束位置。因为考试结束,没法再用考试的测试用例,所以不能保证完全对,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>struct close_info{int num;     // 门编号int close_s; // 门关闭的开始时间int close_e; // 门关闭的结束时间
};// 检查门是否会关闭
bool check_will_close(struct close_info info[], int x[][2], int pos, int time) 
{if (x[pos][0] == -1)   // 没有记录关闭时间,代表一直打开return false;else{for (int i = x[pos][0]; i <= x[pos][1]; i++){if (time >= info[i].close_s && time <= info[i].close_e){return true;}}}return false;
}int cmp(const void *a, const void *b)
{int num1 = ((struct close_info *)a)->num;int num2 = ((struct close_info *)b)->num;return num1-num2;
}int main() 
{int n,m;struct close_info *info;scanf("%d %d",&n, &m);info = (struct close_info *)malloc(sizeof(struct close_info)*m);for (int i = 0; i < m; i++) {scanf("%d %d %d",&info[i].num,&info[i].close_s,&info[i].close_e);}// 对info进行排序qsort(info,m,sizeof(struct close_info),cmp);// for (int i = 0; i < m; i++)// {//     printf("info[%d].num=%d,info[%d].close_s=%d,info[%d].close_e=%d\n",i,info[i].num,i,info[i].close_s,i,info[i].close_e);// }// 记录每道闸门的信息在info中的位置int total = n+2; // 位置编号是0-(n+1)int x[total][2];  // 在info中从x[i][0]到x[i][1]都是闸门i的时刻表 for (int i = 0; i < total; i++)  // 初始化{x[i][1] = x[i][0] = -1;}for (int i = 0; i < m; i++){if (x[info[i].num][0] == -1)x[info[i].num][0] = i;x[info[i].num][1] = i;}// for (int i = 0; i < total; i++)// {//     printf("x[%d][0]=%d,x[%d][1]=%d\n",i,x[i][0],i,x[i][1]);// }int pos = 0;int time = 0;int end = n + 1;int pos_time[total];  // 最后一次在i位置的时间int dead_count = 0;// int dead_pos;while (pos < end) {time++;if (dead_count == 0 && !check_will_close(info, x, pos+1, time)) // 前面的门不会关闭 {pos++;pos_time[pos] = time;continue;}dead_count = 0;// else {if (!check_will_close(info, x, pos, time)) //当前的门不关闭,留在这{pos_time[pos] = time;} else // 当前关闭 {if (!check_will_close(info, x,pos-1, time)) // 后面不关闭 {pos--;pos_time[pos] = time;continue;}else // 死路 {// 时光回溯,回到前一格的位置和时间点,然后选择不前进到下一个门pos--;time = pos_time[pos];dead_count = 1;}}}}printf("%d\n",time);
}
http://www.lryc.cn/news/112933.html

相关文章:

  • Redis入门
  • [CrackMe]BuLLeT.exe的逆向及注册机编写
  • C++ 中 int、short、long和long long 分别是几位?有符号无符号有什么区别?
  • Killing LeetCode [82] 删除排序链表中的重复元素 II
  • LeetCode 热题 100 JavaScript--283. 移动零
  • java读写ini文件
  • 【ARM Coresight 系列文章 2.3 - Coresight 寄存器】
  • kafka:java client使用总结塈seek() VS commitSync()的区别(三)
  • 如何用正确的姿势监听Android屏幕旋转
  • mysql高级三:sql性能优化+索引优化+慢查询日志
  • HCIP VLAN--Hybrid接口
  • 大数据开发面试必问:Hive调优技巧系列二
  • 【C++】STL——list的模拟实现、构造函数、迭代器类的实现、运算符重载、增删查改
  • vscode 插件::EIDE
  • Python 网络编程
  • SQL 数据科学:了解和利用联接
  • (统计学习方法|李航)第五章决策树——四五节:决策树的剪枝,CART算法
  • C语言--结构体定义
  • 解决Element Plus中Select在El Dialog里层级过低的问题(修改select选项框样式)
  • 【数据结构】二叉树 链式结构的相关问题
  • 【无标题】云原生在工业互联网的落地及好处!
  • 人工智能在心电信号分类中的应用
  • 【Linux 网络】网络层协议之IP协议
  • .meta 文件
  • CRITICAL_SECTION 用法
  • 汇川运动控制产品故障排查
  • 【Groups】50 Matplotlib Visualizations, Python实现,源码可复现
  • windows安装kafka配置SASL-PLAIN安全认证
  • 【Linux】五种IO模型
  • SCT82A30DHKR_5.5V-100V Vin同步降压控制器