• 两道 杂题


    1、最少刷题数

    小蓝老师教的编程课有 N 名学生,编号依次是 1...N。

    第 i 号学生这学期刷题的数量是Ai。

    对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题比他多的学生数不超过刷题比他少的学生数。

    输入格式

    第一行包含一个正整数 N。

    第二行包含 N 个整数:A1,A2,A3,...,AN。

    输出格式

    输出 N 个整数,依次表示第 1...N号学生分别至少还要再刷多少道题。

    数据范围

    对于 30%的数据,1≤N≤1000,0≤Ai≤1000。
    对于 100% 的数据,1≤N≤100000,0≤Ai≤100000。

    输入样例:
    1. 5
    2. 12 10 15 20 6
    输出样例:
    0 3 0 0 7

    因为数据会有相等的,所以使用二分。

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define int long long
    4. #define fp(i,a,b) for(int i=a;i<=b;++i)
    5. const int N=1e6+10;
    6. const int mod=1e9+7;
    7. const double eps=1e-5;
    8. typedef double db;
    9. int n;
    10. int mmax;
    11. int a[N],b[N];
    12. bool check(int x,int y)
    13. {
    14. int st=-1;
    15. int ed=-1;
    16. int l=1,r=n;
    17. while(l<r)
    18. {
    19. int mid=(l+r)>>1;
    20. if(b[mid]>=x)r=mid;
    21. else l=mid+1;
    22. }
    23. st=l;
    24. l=1,r=n;
    25. while(l<r)
    26. {
    27. int mid=(l+r+1)>>1;
    28. if(b[mid]<=x)l=mid;
    29. else r=mid-1;
    30. }
    31. ed=l;
    32. int lcnt=st-1;
    33. int rcnt=n-ed;
    34. if(y<x)lcnt--;
    35. if(rcnt<=lcnt)return true;
    36. else return false;
    37. }
    38. signed main()
    39. {
    40. cin>>n;
    41. fp(i,1,n)cin>>a[i],b[i]=a[i],mmax=max(mmax,a[i]);
    42. sort(b+1,b+1+n);
    43. for(int i=1;i<=n;i++)
    44. {
    45. int l=a[i],r=mmax;
    46. while(l<r)
    47. {
    48. int mid=(l+r)>>1;
    49. if(check(mid,a[i]))r=mid;
    50. else l=mid+1;
    51. }
    52. cout<<l-a[i]<<" ";
    53. }
    54. return 0;
    55. }

    2、最大公约数

    题目描述

    给定一个数组,每次操作可以选择数组中任意两个相邻的元素 x, y并将其中的一个元素替换为gcd(x,y),其中 gcd(x,y) 表示 x 和 y 的最大公约数。请问最少需要多少次操作才能让整个数组只含 1。

    输入格式

    输入的第一行包含一个整数 n,表示数组长度

    第二行包含 n 个整数 a1​,a2​,…,an​,相邻两个整数之间用一个空格分隔。

    输出格式

    输出一行包含一个整数,表示最少操作次数。如果无论怎么操作都无法满足要求,输出 −1。

    输入输出样例

    输入 #1

    3
    4 6 9

    输出 #1

    4

    说明/提示

    【评测用例规模与约定】

    • 对于 30% 的评测用例,n≤500,ai​≤1000;
    • 对于 50% 的评测用例,n≤5000,ai​≤10^6;
    • 对于所有评测用例,1≤n≤10^5,1≤ai​≤10^9。

    蓝桥杯 2022 国赛 A 组 D 题。

    首先要使整个数列为 1,必须要先有一个位置的值为 1,再逐步拓展。问题就转化为拼出一个 1 的最少步数。又由于题目要求只能用相邻两数来进行gcd,所以要拼出 1 个 1 必须是一个区间内的数进行 gcd。维护一个区间 gcd,套个双指针就可以了。这里用的是 st 表,时间复杂度O(nlogn+n)。

     

     

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define int long long
    4. #define fp(i,a,b) for(int i=a;i<=b;++i)
    5. const int N=1e5+10;
    6. const int mod=1e9+7;
    7. const double eps=1e-5;
    8. typedef double db;
    9. int Max[N][25];
    10. int lg[N];
    11. int n;
    12. int a[N];
    13. int gcd(int a, int b)
    14. {
    15. return b ? gcd(b, a % b) : a;
    16. }
    17. int query(int l,int r)
    18. {
    19. int k=lg[r-l+1];
    20. return gcd(Max[l][k],Max[r-(1<<k)+1][k]);
    21. }
    22. signed main()
    23. {
    24. cin>>n;
    25. int cnt=0;
    26. fp(i,1,n)
    27. {
    28. cin>>Max[i][0];
    29. a[i]=Max[i][0];
    30. if(a[i]==1)cnt++;
    31. }
    32. for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
    33. for(int j=1;j<=lg[n];j++)
    34. {
    35. for(int i=1;i+(1<<j)-1<=n;i++)
    36. {
    37. Max[i][j]=gcd(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);
    38. }
    39. }
    40. if(cnt)
    41. {
    42. cout<<n-cnt;
    43. return 0;
    44. }
    45. if(query(1,n)>1)
    46. {
    47. cout<<-1;
    48. return 0;
    49. }
    50. int ans=n;
    51. for (int l=1,r=1;r<=n;r++) {
    52. while (l<r && query(l+1,r)==1) l++;
    53. if (query(l,r)==1) ans=min(ans,r-l);
    54. }
    55. cout<<n+ans-1;
    56. return 0;
    57. }

  • 相关阅读:
    坦克大战游戏开发中的设计模式总结
    JSP中的EL 表达式
    【cpu_entry_area mapping】SCTF2023-sycrop
    Acrylamide-PEG-Thiol,ACA-PEG-SH,丙烯酰胺-聚乙二醇-巯基线性双功能PEG试剂
    【Golang星辰图】全面解析:Go语言在Web开发中的顶尖库和框架
    java毕业设计乡镇卫生院信息管理mybatis+源码+调试部署+系统+数据库+lw
    【每日一题】1041. 困于环中的机器人
    &3 在浏览器中查看请求报文和响应报文
    Pytest 自定义HOOK函数
    女生学大数据好就业吗?前景如何?
  • 原文地址:https://blog.csdn.net/m0_61949623/article/details/133513587