• 20年秦皇岛D - Exam Results(二分+思维,附易错数据)


    亚历克斯教授正在为他的学生准备考试。

    将会nn参加本次考试的学生。如果学生ii拥有良好的心态,他/她会表现出色并获得a_iai​分。否则,他/她会得到北京国际机场bi​分。所以不可能预测考试结果。假设这些学生的最高分是xx分。分数不低于的学生x \cdot p\%x⋅p%会通过考试的。

    Alex需要知道在所有情况下能够通过考试的学生人数上限是多少。你能回答他的问题吗?

    投入

    输入的第一行给出了测试用例的数量,T\ (1次10^3)T (1≤T≤5×103). TT测试案例如下。

    对于每个测试用例,第一行包含两个整数n \(1 \ le n \ le 2 \次10^5)n (1≤n≤2×105)和p\ (1 \le p \le 100)p (1≤p≤100),在哪里nn是学生的数量p\%p%就是比例。

    以下每一项nnlines包含两个整数10^9阿乐大学ai​,bi​ (1≤bi​≤ai​≤109),代表学生的分数ii.

    的总和nn在所有测试案例中,不超过5次10^55×105.

    输出

    对于每个测试用例,输出一行包含“案例#x: y“,哪里\texttt{x}x是测试用例编号(从11),以及\texttt{y}y是学生的最大数量。

    样本1

    投入复制输出复制
    2
    2 50
    2 1
    5 1
    5 60
    8 5
    9 3
    14 2
    10 8
    7 6
    
    Case #1: 2
    Case #2: 4

    题意:n个学生是较高分,或者是较低分。使不低于最高分*(m/100)的人数最多

    思路:看别人都是尺取,差分什么,但是不能理解,还好自己的代码终于过了

    个人觉得这个思路还是比较好理解的。

    先结构体排序,按照高分高的(一样的话按低分高的)进行排序,第二个样例就成了下面这样

    1. struct Node
    2. {
    3. int x,y;
    4. bool operator<(const Node temp)const{
    5. if(x!=temp.x) return x>temp.x;
    6. return y>temp.y;
    7. }
    8. }x[M];
    14 2
    10 8
    9 3
    8 5
    7 6

            如果最后的最大值是14,那么其他一定都是最大的,二分查找上升数组中有多少不低于14*(60/100.0)就很简单

            如果最后的最大值是10,那么下面的一定是最大的,第一个不是14,一定会是2,因为14存在的话10不会是最大的。那么答案就是下面较大的答案+上面较小的答案。因为上面较小的答案是没有顺序的,而优先队列不能进行二分查找,可以使用vector进行添加+二分查找,具体下面代码最上面两个函数就是。

    然后对于数据:

    2 50
    100 80
    7 6

    7和6永远不会是最大值,实现这个停止只需要记录前面最大的y为maxxy,if(x[i].x<maxxy) break;即可

    注意最后那个最大的maxxy也是有可能是最大,最后需要再算一遍结果,比如100 80,7 6这个数据,maxxy=80。

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define fo(a,b) for(int i=a;i<=b;i++)
    4. #define inf 0x3f3f3f3f
    5. #define ll long long
    6. const ll mod=998244353;
    7. #define EXP 1e-6
    8. #define M 1000005
    9. int T,n,m,maxxy;
    10. int a[M];
    11. struct Node
    12. {
    13. int x,y;
    14. bool operator<(const Node temp)const{
    15. if(x!=temp.x) return x>temp.x;
    16. return y>temp.y;
    17. }
    18. }x[M];
    19. vector<int>s;
    20. void update(int q){ //差不多以优先队列时间加入
    21. maxxy=max(maxxy,q);
    22. vector<int>::iterator last=lower_bound(s.begin(),s.end(),q);
    23. s.insert(last,q);
    24. }
    25. int solve(double a){ //二分查找
    26. if(s.size()==0) return 0;
    27. return lower_bound(s.begin(),s.end(),a)-s.begin();
    28. }
    29. signed main()
    30. {
    31. scanf("%d",&T);
    32. for(int k=1;k<=T;k++){
    33. int maxx=0;
    34. maxxy=0;
    35. s.clear();
    36. scanf("%d%d",&n,&m);
    37. fo(1,n) scanf("%d%d",&x[i].x,&x[i].y);
    38. sort(x+1,x+n+1);
    39. fo(1,n) a[i]=x[n-i+1].x;
    40. for(int i=1;i<=n;i++){
    41. if(x[i].x<maxxy) break; //如果较高分无法成为最大值
    42. double r=x[i].x*(m/100.0);
    43. int sum=(n-i)-(lower_bound(a+1,a+n+1-i,r)-a)+2; //下面的
    44. sum+=i-solve(r)-1; //上面的
    45. maxx=max(maxx,sum);
    46. update(x[i].y);
    47. }
    48. double r=maxxy*(m/100.0);
    49. int sum=0;
    50. for(int i=1;i<=n;i++){ //maxxy为最大值时的答案
    51. sum+=(x[i].x>maxxy?(x[i].y>=r):(x[i].x>=r));
    52. }
    53. maxx=max(maxx,sum);
    54. printf("Case #%d: %d\n",k,maxx);
    55. }
    56. return 0;
    57. }
    58. /*
    59. 一些易错的数据:
    60. 1
    61. 3 50
    62. 100 6
    63. 5 4
    64. 6 4
    65. :3
    66. 1
    67. 2 50
    68. 5 5
    69. 2 2
    70. :2
    71. 1
    72. 3 50
    73. 100 6
    74. 5 4
    75. 5 4
    76. :3
    77. */

  • 相关阅读:
    java生成自定义长度的唯一随机字符串
    (其他) 剑指 Offer 64. 求1+2+…+n ——【Leetcode每日一题】
    LabVIEW调试技巧
    vCenter 物理配置与虚拟机配置对应关系
    【web实战-业务逻辑】评论点赞逻辑
    【力扣刷题】Day09——字符串专题
    数字化安全方案建设
    真正理解浏览器渲染更新流程
    Kubernetes(k8s)网络策略NetworkPolicy
    股东入股可用的出资形式主要有哪些
  • 原文地址:https://blog.csdn.net/m0_58177653/article/details/125476720