• Codeforces Round 895 (Div. 3) (A~G)


    A. Two Vessels

    题意:你有两个无限容量杯子A,B,分别装了a,b升的水,此外你还有一个容量为c的杯子C,你可以将一杯的水先倒入C中,再倒入另一个杯子,问你最少需要操作几次能使得A B杯的水量相同。

    解析:初始两杯相差d升,其实就是问你 d对2*c向上取整

    1. void solve()
    2. {
    3. int a,b,c;
    4. scanf("%d%d%d",&a,&b,&c);
    5. c*=2;
    6. int d=abs(a-b);
    7. if(d==0)
    8. {
    9. printf("0\n");
    10. return;
    11. }
    12. printf("%d\n",(d-1)/c+1);
    13. }

    B. The Corridor or There and Back Again

    题意:有一个无限长的房间,有n个陷阱,每个陷阱有两个参数d,s表示该陷阱只有你到达d房间之后再经过s秒激活,问你最多能到多远且能安全返回。

    解析:其实我们考虑一个陷阱,对于该陷阱,我们最多能再走(s-1)/2个房间(安全来回),因此对于每一个陷阱,计算能到的最远房间与答案取min即可。

    1. void solve()
    2. {
    3. int n,ans=1e9;//初始化答案
    4. scanf("%d",&n);
    5. for(int i=1;i<=n;i++)
    6. {
    7. int d,s;
    8. scanf("%d%d",&d,&s);
    9. ans=min(ans,d+(s-1)/2);
    10. }
    11. printf("%d\n",ans);
    12. }

    C. Non-coprime Split

    题意:给定L,R,问你是否存在两个数a,b,满足a+b在[L,R]中且gcd(a,b)不等于1。

    解析:1.其实发现只要区间长度>=2,那么肯定有偶数,因此我们设立a=2,只要在区间中找到一个偶数,两者gcd肯定是2,即为可行解。  2.如果L=R,那么只要L存在非1的因子,那么就是有解,因此假设x是L的因子,那么L/x就是另一部分,那么两者gcd就是x,且相加是L。

    1. void solve()
    2. {
    3. int L,R,a=2;
    4. scanf("%d%d",&L,&R);
    5. for(int i=L-2;i<=R-2;i++)
    6. {
    7. if(i%2==0&&i>0)//需要正整数
    8. {
    9. printf("2 %d\n",i);
    10. return;
    11. }
    12. }
    13. if(L==R)
    14. {
    15. for(int i=2;i<=L/i;i++)//寻找因子
    16. {
    17. if(L%i==0)
    18. {
    19. printf("%d %d\n",i,L-i);
    20. return;
    21. }
    22. }
    23. }
    24. printf("-1\n");
    25. }

    D. Plus Minus Permutation

    题意:给定n,x,y,定义价值为(p1⋅x+p2⋅x+…+p⌊n/x⌋⋅x)−(p1⋅y+p2⋅y+…+p⌊n/y⌋⋅y),p表示n的排列,问你重新排列1~n,使得价值最大化,输出这个价值。

    解析:前一半有⌊n/x⌋个数,后一半有⌊n/y⌋个数,那么我们优先选择n,n-1,n-2....填充前面⌊n/x⌋个位置,后一半选择1,2,3...填充,但其中其实可能有重复的位置,重复位置肯定就等价抵消了,计算非重复的即可,重复的个数就是n除以两者的最小公倍数。

    1. void solve()
    2. {
    3. ll n,x,y;
    4. scanf("%lld%lld%lld",&n,&x,&y);
    5. ll k=x*y/__gcd(x,y);//最小公倍数
    6. ll w=n/k;//重复的个数
    7. ll s1=n/x-w,s2=n/y-w;//前一般有s1个数,后一半有s2个数
    8. ll a=s1*n-(s1-1)*s1/2;//数学公式算一下即可
    9. ll b=(1+s2)*s2/2;
    10. printf("%lld\n",a-b);
    11. }

    E. Data Structures Fan

    题意:有n个数,同时给长度为n的 01串,有q次询问,其中有两种操作"1  L  R"和"2  g (  g=0 || g=1 )"分别表示把区间[L,R]中的01反转,0变1,1变0,第二种表示询问01串中等于g的所有位置 i 对应的ai异或,输出这个值。

    解析:翻转区间[l,r],对于总的s[i]=0的异或总和ans0刚好就是 ans0^=(a[l]^a[l+1]^...^a[r]),ans1同理,因此维护一下异或前缀和即可。

    1. int a[N],b[N];
    2. char s[N];
    3. void solve()
    4. {
    5. int n;
    6. scanf("%d",&n);
    7. for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    8. scanf("%s",s+1);
    9. for(int i=1;i<=n;i++) b[i]=b[i-1]^a[i];
    10. int ans0=0,ans1=0;
    11. for(int i=1;i<=n;i++)
    12. {
    13. if(s[i]=='0') ans0^=a[i];
    14. else ans1^=a[i];
    15. }
    16. int q;
    17. scanf("%d",&q);
    18. while(q--)
    19. {
    20. int op;
    21. scanf("%d",&op);
    22. if(op==1)
    23. {
    24. int l,r;
    25. scanf("%d%d",&l,&r);
    26. ans0^=b[r]^b[l-1];
    27. ans1^=b[r]^b[l-1];
    28. }else
    29. {
    30. int g;
    31. scanf("%d",&g);
    32. if(g==0) printf("%d ",ans0);
    33. else printf("%d ",ans1);
    34. }
    35. }
    36. printf("\n");
    37. }

    F. Selling a Menagerie

    题意:有n个动物,每个动物有价值wi,每个动物有一个前置点,如果售卖该动物时,他的前置点还没有被卖,那么你会获得2*wi,否则获得wi,要求你输出一个售卖动物的顺序,是否获得价值最大。

    解析:假设关系是一条链,那么肯定是从最后一个点(入度为0)开始卖,直到第一个点,这样价值肯定是最大的,但题中其实会出现有环的情况,但其实不复杂,我们只要使得损失最小即可,我们可以选择环中价值最低的那一个最后卖即可,非环的跑一次拓扑即可,怎么判断该点是否在环中呢,其实跑完拓扑,没有遍历到的点就是在环中。

    1. typedef long long ll;
    2. vector<int> v[N],ans;
    3. ll w[N];//每个点的价值
    4. int n,d[N],ne[N];//分别记录入度和当前点的前置点
    5. bool vis[N];//表示该点是否访问过
    6. void topsort()
    7. {
    8. queue<int> q;
    9. for(int i=1;i<=n;i++)
    10. {
    11. if(!d[i])
    12. {
    13. q.push(i);
    14. ans.push_back(i);
    15. vis[i]=true;
    16. }
    17. }
    18. while(q.size())
    19. {
    20. int x=q.front();
    21. q.pop();
    22. for(int i=0;isize();i++)
    23. {
    24. int j=v[x][i];
    25. if(--d[j]==0)
    26. {
    27. ans.push_back(j);
    28. vis[j]=true;
    29. q.push(j);
    30. }
    31. }
    32. }
    33. }
    34. void solve()
    35. {
    36. scanf("%d",&n);
    37. for(int i=1;i<=n;i++)
    38. {
    39. int x;
    40. scanf("%d",&x),v[i].push_back(x);
    41. ne[i]=x;//下一个节点
    42. d[x]++;
    43. }
    44. for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
    45. topsort();
    46. for(int i=1;i<=n;i++)
    47. {
    48. if(!vis[i])//还没访问过,表示在环中
    49. {
    50. int root=i,pos=i;
    51. ll mi=w[root];
    52. while(1)
    53. {
    54. int k=ne[pos];//下一个节点
    55. if(k==root) break;//如果回到了自身退出
    56. if(w[k]
    57. {
    58. mi=w[k];
    59. root=k;//记录环中最小值
    60. }
    61. pos=k;
    62. }
    63. pos=root;
    64. while(1)//从root开始跑一次环,记录答案
    65. {
    66. int k=ne[pos];
    67. if(k==root) break;
    68. ans.push_back(k);
    69. vis[k]=true;
    70. pos=k;
    71. }
    72. ans.push_back(root);//最后把root放进答案
    73. vis[root]=true;
    74. }
    75. }
    76. for(int i=0;isize();i++) printf("%d ",ans[i]);
    77. printf("\n");
    78. for(int i=1;i<=n;i++) d[i]=0,v[i].clear(),vis[i]=false;//多组初始化
    79. ans.clear();
    80. }

    G. Replace With Product

    题意:给定n个数,你可以仅操作一次,使得[L,R]这一段替换区间乘积,让你输出L,R使得最后序列总和最大。

    解析:正常来贪,肯定选择第一个非1到最后一个非1这个区间,但有些情况并不满足,但是如果区间乘积>=1e9之后,肯定就是选择上述区间,对于总的乘积<1e9的情况,可以发现>1的个数肯定 很少,直接暴力枚举每对位置即可,当然可以用前缀和以及前缀积优化,对于每种跟答案取max即可。

    1. typedef long long ll;
    2. ll a[N],sum[N],mul[N];//分别表示原数组,前缀和,前缀积
    3. void solve()
    4. {
    5. int n,l=-1,r=-1;//表示答案区间
    6. ll s=1;
    7. vector<int> v;
    8. scanf("%d",&n);
    9. mul[0]=1;//初始化
    10. for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    11. for(int i=1;i<=n;i++)
    12. {
    13. if(a[i]!=1)
    14. {
    15. v.push_back(i);
    16. if(l==-1) l=i;//第一个非1数字
    17. r=i;//最后一个非1数字
    18. }
    19. sum[i]=sum[i-1]+a[i];
    20. mul[i]=mul[i-1]*a[i];
    21. }
    22. for(int i=1;i<=n;i++)
    23. {
    24. s*=a[i];
    25. if(s>=1e9)
    26. {
    27. printf("%d %d\n",l,r);
    28. return;
    29. }
    30. }
    31. ll mx=0;
    32. for(int i=0;isize();i++)
    33. {
    34. for(int j=i;jsize();j++)
    35. {
    36. int x=v[i],y=v[j];
    37. if(sum[x-1]+mul[y]/mul[x-1]+sum[n]-sum[y]>mx)
    38. {
    39. mx=sum[x-1]+mul[y]/mul[x-1]+sum[n]-sum[y];
    40. l=x,r=y;
    41. }
    42. }
    43. }
    44. if(l==-1) l=1,r=1;
    45. printf("%d %d\n",l,r);
    46. }
  • 相关阅读:
    【设计模式4_建造者、装饰者、代理】
    【项目结构】
    SpringCloud - Nacos 结合 K8s 优雅关闭服务(平滑升级)
    【软件测试】性能测试工具Loadrunner
    铁威马新品F2-212上线,全新设计,极致使用体验
    使用pytorch搭建MobileNetV2并基于迁移学习训练
    Nodejs安装教程
    2023年最大规模的IPO正式诞生,Arm市值4700亿
    Win10添加、删除鼠标右击的选项(快捷方法)
    金仓数据库KingbaseES immutable 与 stable 函数的差异
  • 原文地址:https://blog.csdn.net/qq_63739337/article/details/132778436