当前位置:   article > 正文

2023 RoboCom CAIP本科组决赛-RC-u3 兰州拉面派餐系统

2023 RoboCom CAIP本科组决赛-RC-u3 兰州拉面派餐系统

1.题目

题目链接:RC-u3 兰州拉面派餐系统 - 2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛) (pintia.cn)

2. 具体实现

模拟过程即可

2.1 普通方法

  1. //模拟
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int times[10010]; //每种面需要的时间
  5. int cus[100010]; //每个客户各自需要的时间
  6. int num[10010]; //记录每个篮子煮了多少次面
  7. int order[10010]; //记录每个篮子装的是哪位顾客的
  8. int shengy[10010]; //记录每个篮子面还需要多久
  9. map<int,int> p; //存储出单次序+最小坐标
  10. vector<int> p1; //按照菜篮顺序
  11. int n,m,l;
  12. int temp;
  13. int getMin(){
  14. p.clear();
  15. p1.clear();
  16. int mi=0x3f3f3f3f;
  17. for(int i=1;i<=m;i++){
  18. if(shengy[i]!=0&&shengy[i]<mi)
  19. mi=shengy[i];
  20. }
  21. //找到最小值的坐标
  22. for(int i=1;i<=m;i++){
  23. if(mi==shengy[i]){
  24. p1.push_back(i);
  25. int o=order[i]; //记录是哪一位顾客的
  26. p[o]=i;
  27. }
  28. }
  29. return mi;
  30. }
  31. //判断是否都煮好了
  32. bool judge(){
  33. for(int i=1;i<=m;i++){
  34. if(shengy[i]!=0)
  35. return false;
  36. }
  37. return true;
  38. }
  39. int main(void){
  40. cin>>n>>m>>l; //面的种类数、篮子个数
  41. for(int i=1;i<=n;i++){
  42. cin>>times[i];
  43. }
  44. for(int i=1;i<=l;i++){
  45. int t;
  46. cin>>t;
  47. cus[i]=times[t];
  48. }
  49. //初始化
  50. for(int i=1;i<=min(m,l);i++){
  51. order[i]=i;
  52. num[i]=1;
  53. shengy[i]=cus[i];
  54. }
  55. int tim=min(m,l); //表示已经煮了第几客单
  56. //模拟
  57. int t=0; //经过的时间
  58. bool flag=true; //false表示不是第一个
  59. while(1){
  60. int minz=getMin();
  61. //p存储位置,找到位置,将值归为0,客单拿出来
  62. t+=minz;
  63. //所有剩余都要减去
  64. for(int i=1;i<=m;i++){
  65. if(shengy[i]!=0)
  66. shengy[i]-=minz;
  67. }
  68. //捞出
  69. for(auto x:p){
  70. int o=x.first; //次序(第几个客人)
  71. if(!flag) cout<<" ";
  72. flag=false;
  73. // int z=x.second; //坐标
  74. cout<<o<<":"<<t;
  75. }
  76. //加面
  77. for(int i=0;i<p1.size();i++){
  78. if(tim<l){
  79. tim++;
  80. shengy[p1[i]]=cus[tim];
  81. order[p1[i]]=tim;
  82. num[p1[i]]++;
  83. }
  84. }
  85. if(judge()){
  86. break;
  87. }
  88. }
  89. cout<<endl;
  90. for(int i=1;i<=m;i++){
  91. if(i!=1) cout<<" ";
  92. cout<<num[i];
  93. }
  94. return 0;
  95. }

2.2 使用优先队列

  1. //捞面:每个篮子按时间短的先,如果时间相同,按篮子序号从小到大
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int N=1010;
  5. const int M=10010;
  6. //第一个捞出的位置
  7. //时间最早,如果时间相同,捞出lanzi最小的面
  8. struct node{
  9. int lanzi; //第几个篮子
  10. int tt; //需要的时间
  11. int order; //派单序号
  12. bool operator<(const node& a) const{
  13. return tt==a.tt?lanzi>a.lanzi:tt>a.tt;
  14. }
  15. };
  16. priority_queue<node> p;
  17. int times[N]; //每种面所需要的时间
  18. queue<pair<int,int> > q; //客单顺序、面的种类
  19. vector<pair<int,int>> res; //编号、时间
  20. int num[M]; //记录篮子的使用次数
  21. int main(void){
  22. int n,m,l;
  23. cin>>n>>m>>l;
  24. for(int i=1;i<=n;i++){
  25. cin>>times[i];
  26. }
  27. for(int i=1;i<=l;i++){
  28. int t;
  29. cin>>t;
  30. q.push({i,t});
  31. }
  32. //模拟场景
  33. int cnt=1; //用于分配的篮子编号
  34. while(!q.empty()){
  35. auto z=q.front();
  36. q.pop();
  37. if(cnt<=m){ //表明还有空闲篮子
  38. p.push({cnt,times[z.second],z.first});
  39. num[cnt++]++;
  40. }else{
  41. //t就是我们捞出的地方
  42. node t=p.top();
  43. p.pop();
  44. res.push_back({t.tt,t.order});
  45. p.push({t.lanzi,t.tt+times[z.second],z.first});
  46. num[t.lanzi]++;
  47. }
  48. }
  49. while(p.size()){
  50. auto z=p.top();
  51. p.pop();
  52. res.push_back({z.tt,z.order});
  53. }
  54. sort(res.begin(),res.end());
  55. //输出结果
  56. for(int i=0;i<res.size();i++){
  57. if(i!=0) cout<<" ";
  58. cout<<res[i].second<<":"<<res[i].first;
  59. }
  60. cout<<endl;
  61. for(int i=1;i<=m;i++){
  62. if(i!=1) cout<<" ";
  63. cout<<num[i];
  64. }
  65. return 0;
  66. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/940035
推荐阅读
相关标签
  

闽ICP备14008679号