• 蓝桥杯每日一题2023.10.4


    双向排序 - 蓝桥云课 (lanqiao.cn)

    题目描述

    题目分析 

    六十分解法如下:按照题意简单排序

    1. #include
    2. using namespace std;
    3. const int N = 2e5 + 10;
    4. int n, m, p, q, a[N];
    5. bool cmp(int x, int y)
    6. {
    7. return x > y;
    8. }
    9. int main()
    10. {
    11. cin >> n >> m;
    12. for(int i = 1; i <= n; i ++)a[i] = i;
    13. for(int i = 1; i <= m; i ++)
    14. {
    15. cin >> p >> q;
    16. if(p == 0)sort(a + 1, a + 1 + q, cmp);
    17. else sort(a + q, a + 1 + n);
    18. }
    19. for(int i = 1; i <= n; i ++)cout << a[i] << ' ';
    20. return 0;
    21. }

    满分解法: 

    对于每一次操作我们在每次连续的升序和降序操作中只需要选呢个范围最大的即可,范围小的操作对于范围大的操作相当于重复没用的操作,因此我们正真需要的操作是升序降序依次交替出现的,第一个有效操作一定为p = 0,因为刚开始一定是升序的,再进行升序操作是无效操作

    在排序中会不断有数字被固定

     

    由于升降交替排序,先将[1, x]降序排序,再将[y, n]升序排序,这里y <= x,我们可以发现[x, n]这段会被固定而不发生变化

    同理,先将[x, n]升序排序,再将[1, y]降序排序,这里y <= x,我们可以发现[1, y]这段会被固定而不发生变化

    使用ans不断记录被固定的数,最后没固定的再看其操作,

    由于第一个有效操作一定是p = 0,故如果剩余的操作次数为奇数相当于降序操作确定了[x, n]的位置,如果为偶数个操作次数就相当于后缀做升序,就意味着确定前缀[1, y]的位置

    1. #include
    2. using namespace std;
    3. const int N = 2e5 + 10;
    4. pair<int, int> stk[N];
    5. int n, m, top, p, q, ans[N];
    6. int main()
    7. {
    8. cin >> n >> m;
    9. while(m --)
    10. {
    11. cin >> p >> q;
    12. if(p == 0)
    13. {
    14. while(top && stk[top].first == 0)
    15. {
    16. q = max(q, stk[top --].second);
    17. }
    18. //123456
    19. //321456
    20. //432156
    21. while(top >= 2 && stk[top - 1].second <= q)
    22. {//如上,如果当前操作比上一次相同操作的范围大,那此次操作的前两次操作都将被无效化
    23. top -= 2;
    24. }
    25. stk[++top] = {0, q};
    26. }
    27. else if(top)
    28. {
    29. while(top && stk[top].first == 1)
    30. {
    31. q = min(q, stk[top --].second);
    32. }
    33. while(top >= 2 && stk[top - 1].second >= q)
    34. {
    35. top -= 2;
    36. }
    37. stk[++ top] = {1, q};
    38. }
    39. }
    40. int left = 1, right = n, k = n;
    41. for(int i = 1; i <= top; i ++)
    42. {
    43. if(stk[i].first == 0)
    44. {
    45. while(right > stk[i].second && left <= right)//确定[x, n]
    46. {
    47. ans[right --] = k --;
    48. }
    49. }
    50. else
    51. {
    52. while(left < stk[i].second && left <= right)//确定[1, y]
    53. {
    54. ans[left ++] = k --;
    55. }
    56. }
    57. if(left > right)break;
    58. }
    59. if(top % 2)
    60. {
    61. while(left <= right)ans[left ++] = k --;
    62. }
    63. else
    64. {
    65. while(left <= right)ans[right --] = k --;
    66. }
    67. for(int i = 1; i <= n; i ++)
    68. {
    69. cout << ans[i] << ' ';
    70. }
    71. return 0;
    72. }
  • 相关阅读:
    项目系列之登录管理
    Docker基于Minio搭建对象(文件)存储服务
    FPGA行业应用二:通用仪器行业
    Android入门第24天-Adapter使用初步-最简单的一个Adapter的使用
    SpringBoot笔记之模板引擎
    横向知识总结
    基于JavaSwing开发银行排号系统 课程设计 大作业 毕业设计
    双软认证是指软件产品登记和软件企业认定
    Redis常见面试问题总结
    【Kubernetes | Pod 系列】Pod的 YAML 清单文件详解
  • 原文地址:https://blog.csdn.net/m0_75087931/article/details/133561119