• POJ 3481:双端队列 ← 数组模拟


    【题目来源】
    http://poj.org/problem?id=3481

    【题目描述】
    某银行的业务处理系统原理如下。
    初始时,待处理业务队列(简称为队列)为空。
    接下来,系统会收到一系列的请求,请求分为以下四种:
    ● 0,表示系统需要停止服务。
    ● 1 K P,表示收到一个来自客户 K 的优先级为 P 的待处理业务,并将该业务加入队列。
    ● 2,表示处理当前队列中优先级最高的待处理业务,并将该业务从队列中删除。
    ● 3,表示处理当前队列中优先级最低的待处理业务,并将该业务从队列中删除。
    保证在任何时候,当前队列中的现有待处理业务都满足:不会有多个待处理业务来自同一客户,也不会有多个待处理业务优先级相同。
    也就是说,在完成某客户的待处理业务之前,不会再次收到该客户的待处理业务;在完成某优先级的待处理业务之前,不会再次收到该优先级的待处理业务。
    给定银行系统收到的所有请求,请你模拟系统处理过程。

    【输入格式】
    输入若干行,每行包含一个请求,格式如题面描述。
    数据保证有且仅有最后一行包含请求 0。

    【输出格式】
    对于每个请求 2 和 3,输出一行结果,一个整数,表示此次请求处理业务的客户编号。如果没有可处理业务,则输出 0。

    【数据范围】
    输入最多包含 10^6 个请求。
    1≤K≤10^6,
    1≤P≤10^7。

    【输入样例】
    2
    1 20 14
    1 30 3
    2
    1 10 99
    3
    2
    2
    0

    【输出样例】
    0
    20
    30
    10
    0

    【算法分析】
    虽然本题来源于三个刷题网站:
    POJ 3481:
    http://poj.org/problem?id=3481
    HDU 1908:http://acm.hdu.edu.cn/showproblem.php?pid=1908
    AcWing 5125:https://www.acwing.com/problem/content/5128/

    但是,下文使用
    数组模拟的代码仅在 POJ 3481 上通过,而在 HDU 1908 及 AcWing 5125 上均超时。故可考虑使用 STL map 来实现,经验证,使用 STL map 实现的代码可在 POJ 3481、HDU 1908、AcWing 5125 上均通过
    大家学习时,请优先使用下文中的【算法代码(STL map 1)】进行学习。若想学习切题的数组模拟法实现,请参见本文最后一个代码【算法代码(数组模拟)】。

    【算法代码(
    STL map 1)】

    1. #include
    2. #include
    3. using namespace std;
    4. map<int,int> mp;
    5. map<int,int>::iterator it;
    6. int K,P;
    7. int cnt;
    8. int main() {
    9. int op;
    10. while(~scanf("%d",&op)) {
    11. if(op==0) break;
    12. if(op==1) {
    13. scanf("%d%d",&K,&P);
    14. mp[P]=K;
    15. cnt++;
    16. }
    17. if(op==2) {
    18. if(cnt==0) printf("0\n");
    19. else {
    20. it=mp.end();
    21. it--;
    22. printf("%d\n",it->second);
    23. mp.erase(it);
    24. cnt--;
    25. }
    26. }
    27. if(op==3) {
    28. if(cnt==0) printf("0\n");
    29. else {
    30. it=mp.begin();
    31. printf("%d\n",it->second);
    32. mp.erase(it);
    33. cnt--;
    34. }
    35. }
    36. }
    37. return 0;
    38. }
    39. /*
    40. in:
    41. 2
    42. 1 20 14
    43. 1 30 3
    44. 2
    45. 1 10 99
    46. 3
    47. 2
    48. 2
    49. 0
    50. out:
    51. 0
    52. 20
    53. 30
    54. 10
    55. 0
    56. */


    【算法代码(STL map 2)】

    1. #include
    2. #include
    3. using namespace std;
    4. map<int,int> mp;
    5. int main() {
    6. int K,P;
    7. int op;
    8. while(~scanf("%d",&op)) {
    9. if(op==0) break;
    10. if(op==2 && mp.size()==0) {
    11. printf("0\n");
    12. continue;
    13. }
    14. if(op==3 && mp.size()==0) {
    15. printf("0\n");
    16. continue;
    17. }
    18. if(op==1) {
    19. scanf("%d%d",&K,&P);
    20. mp[P]=K;
    21. continue;
    22. }
    23. if(op==2) {
    24. printf("%d\n",(*mp.rbegin()).second);
    25. mp.erase(mp.find((*mp.rbegin()).first));
    26. } else {
    27. printf("%d\n",(*mp.begin()).second);
    28. mp.erase(mp.begin());
    29. }
    30. }
    31. return 0;
    32. }
    33. /*
    34. in:
    35. 2
    36. 1 20 14
    37. 1 30 3
    38. 2
    39. 1 10 99
    40. 3
    41. 2
    42. 2
    43. 0
    44. out:
    45. 0
    46. 20
    47. 30
    48. 10
    49. 0
    50. */


    【算法代码(数组模拟)】

    1. #include
    2. using namespace std;
    3. const int N=1E7+5;
    4. struct Queue {
    5. int K;
    6. int P;
    7. } q[N];
    8. int hh=0;
    9. int tt=-1;
    10. int cnt;
    11. int pos; //Position of inserting into the queue
    12. int a,b;
    13. int main() {
    14. int n;
    15. while(scanf("%d",&n)!=EOF,n) {
    16. if(n==1) {
    17. scanf("%d %d",&a,&b);
    18. if(tt
    19. q[hh].K=a;
    20. q[hh].P=b;
    21. tt=hh;
    22. } else {
    23. pos=tt+1;
    24. for(int i=hh; i<=tt; i++) {
    25. if(b
    26. pos=i;
    27. break;
    28. }
    29. }
    30. for(int j=tt; j>=pos; j--) {
    31. q[j+1].P=q[j].P;
    32. q[j+1].K=q[j].K;
    33. }
    34. q[pos].P=b;
    35. q[pos].K=a;
    36. tt++;
    37. }
    38. cnt++;
    39. } else if(n==3) {
    40. if(tt-hh>=0 && cnt) {
    41. printf("%d\n",q[hh].K);
    42. hh++;
    43. } else printf("0\n");
    44. if(cnt) cnt--;
    45. } else if(n==2) {
    46. if(tt-hh>=0 && cnt) {
    47. printf("%d\n",q[tt].K);
    48. q[tt].K=q[tt].P=0;
    49. tt--;
    50. } else printf("0\n");
    51. if(cnt) cnt--;
    52. }
    53. }
    54. return 0;
    55. }
    56. /*
    57. in:
    58. 2
    59. 1 20 14
    60. 1 30 3
    61. 2
    62. 1 10 99
    63. 3
    64. 2
    65. 2
    66. 0
    67. out:
    68. 0
    69. 20
    70. 30
    71. 10
    72. 0
    73. */




    【参考文献】
    https://blog.csdn.net/spark_007/article/details/8810139
    https://blog.csdn.net/weixin_44226181/article/details/126758131
    https://www.w3xue.com/exp/article/201811/6221.html








     

  • 相关阅读:
    创新家庭办公室:打造完美工作空间的秘诀
    物联网硬件设计开发全攻略:十大关键阶段深度解析
    用CSS+SVG做一个优雅的环形进度条
    代码随想录day43:动态规划part05:01背包
    【服务器数据恢复】raidz多块硬盘离线的数据恢复案例
    离线密码破解(1)
    东风至,数智生 | “算力+”发力工业互联网,助迎新突破
    OpenCV图像处理——光流估计
    go开发调试之Delve的使用
    如何使用Vcluster实现Kubernetes中的多租户
  • 原文地址:https://blog.csdn.net/hnjzsyjyj/article/details/133693132