当前位置:   article > 正文

Codeforces Round 916 (Div. 3)(A~E题解)

Codeforces Round 916 (Div. 3)(A~E题解)

今天也是小小的vp了一下这场比赛,我对这场比赛的感觉就是比我之前做的都要简单,最简单的一次div3(个人感觉)

话不多说来看这次比赛

A. Problemsolving Log

题解:这题就是说,对于每个问题,其解决时间是按照26个英文字母顺序来规定的解题时间,A题1分钟做完,Z题26分钟做完,然后给你一个字符串说明每分钟都在做哪道题,只要做这道题的时间大于等于解题时间,就说明把这道题做出来了

然后我们就可以遍历一遍字符串统计每道题的做题时间,然后去和题目中解题时间比较,只要大于等于就说明解出来一道题

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. int t,n;
  5. char s[505];
  6. int vis[30];
  7. signed main()
  8. {
  9. cin>>t;
  10. while(t--)
  11. {
  12. memset(vis,0,sizeof(vis));
  13. cin>>n;
  14. cin>>s;
  15. for(int i=0;i<n;i++)
  16. {
  17. vis[s[i]-'A'+1]++;
  18. }
  19. int ans=0;
  20. for(int i=1;i<=26;i++)
  21. {
  22. if(vis[i]>=i)
  23. ans++;
  24. }
  25. cout<<ans<<"\n";
  26. }
  27. return 0;
  28. }

 B. Preparing for the Contest

题解:很水的一道构造题,真的巨水,他想让我们求出有n个数,有k次兴奋的序列,什么时候有兴奋呢?当a[ i+1 ]> a[ i ]的时候会产生一次兴奋,那么我们就可以说,保证前k个数不变,然后将后面所有数进行倒序排列就直接解决了

  1. //明显的构造题
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. #define int long long
  5. int t;
  6. int n,k;
  7. int a[55];
  8. signed main()
  9. {
  10. cin>>t;
  11. while(t--)
  12. {
  13. cin>>n>>k;
  14. for(int i=1;i<=n;i++)
  15. a[i]=i;
  16. int l=k+1,r=n;
  17. while(l<=r)
  18. {
  19. int t=a[l];
  20. a[l]=a[r];
  21. a[r]=t;
  22. l++,r--;
  23. }
  24. for(int i=1;i<=n;i++)
  25. printf("%lld ",a[i]);
  26. cout<<"\n";
  27. }
  28. return 0;
  29. }

C. Quests 

 

题解:一开始刚看题我还以为是动态规划里面和那个五倍经验日很像的问题,等看完题我才发现,啥呀,就是一个简单的前缀和,然后暴力枚举每一种情况即可,唯一需要注意到的细节就是n和k的大小,因为k>n是一定可以将所有任务遍历一遍的

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. int t,n,k;
  5. int a[200005];
  6. int b[200005];
  7. int sum[200005];//前缀和数组,要统计做到第i个任务时,所能获得的总的经验
  8. signed main()
  9. {
  10. cin>>t;
  11. while(t--)
  12. {
  13. memset(sum,0,sizeof(sum));
  14. cin>>n>>k;
  15. for(int i=1;i<=n;i++)
  16. {
  17. cin>>a[i];
  18. sum[i]=sum[i-1]+a[i];
  19. }
  20. int maxn=0;//统计对于前i个任务,最大的重复做后面几次的最大经验值
  21. for(int i=1;i<=n;i++)
  22. {
  23. cin>>b[i];
  24. }
  25. int ans=0;//统计最大经验值
  26. for(int i=1;i<=min(n,k);i++)
  27. {
  28. if(b[i]>maxn)
  29. maxn=b[i];
  30. int flag=sum[i]+(k-i)*maxn;
  31. ans=max(ans,flag);
  32. }
  33. cout<<ans<<"\n";
  34. }
  35. return 0;
  36. }

 D. Three Activities

 题解:这题怎么说呢,说难也难,说简单也简单,反正我错了三次,现在想来还是当时太蠢了,竟然想要枚举出来,一直靠if去判断条件

这题的正解是将三个活动都用一个结构体存起来,结构体里面放的一个是人数,还有一个是天数,然后对结构体数组进行排序,找到人数最多的后面三天,然后搞一个三重循环,遍历每个活动人最多的三天就可以,如果三天各自没有挤在一天就可以更新记录人数最多的ans的值

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. int t;
  5. int n;
  6. struct node1
  7. {
  8. int flag;//下标位置
  9. int ans;//人数
  10. }a[100005];
  11. struct node2
  12. {
  13. int flag;//下标位置
  14. int ans;//人数
  15. }b[100005];
  16. struct node3
  17. {
  18. int flag;//下标位置
  19. int ans;//人数
  20. }c[100005];
  21. bool cmp1(node1 a,node1 b)
  22. {
  23. return a.ans>b.ans;
  24. }
  25. bool cmp2(node2 a,node2 b)
  26. {
  27. return a.ans>b.ans;
  28. }
  29. bool cmp3(node3 a,node3 b)
  30. {
  31. return a.ans>b.ans;
  32. }
  33. signed main()
  34. {
  35. cin>>t;
  36. while(t--)
  37. {
  38. cin>>n;
  39. for(int i=1;i<=n;i++)
  40. {
  41. cin>>a[i].ans;
  42. a[i].flag=i;
  43. }
  44. for(int i=1;i<=n;i++)
  45. {
  46. cin>>b[i].ans;
  47. b[i].flag=i;
  48. }
  49. for(int i=1;i<=n;i++)
  50. {
  51. cin>>c[i].ans;
  52. c[i].flag=i;
  53. }
  54. sort(a+1,a+1+n,cmp1);
  55. sort(b+1,b+1+n,cmp2);
  56. sort(c+1,c+1+n,cmp3);
  57. int ans=0;
  58. for(int i=1;i<=3;i++)
  59. {
  60. for(int j=1;j<=3;j++)
  61. {
  62. for(int k=1;k<=3;k++)
  63. {
  64. if(a[i].flag!=b[j].flag&&a[i].flag!=c[k].flag&&b[j].flag!=c[k].flag)
  65. {
  66. ans=max(ans,a[i].ans+b[j].ans+c[k].ans);
  67. }
  68. }
  69. }
  70. }
  71. cout<<ans<<"\n";
  72. }
  73. return 0;
  74. }

E2. Game with Marbles (Hard Version)

 

 

 题解:简单版本和这个版本一个代码,最主要是要去学到其中的数学思维,会了那个思维就都可以解决了

首先我们可以知道,如果谁都无法做出选择,那么最后的得分一定是每一项a[i]-b[i]的和

首先我们考虑爱丽丝的影响,如果爱丽丝不选i那么原本对于这一项的值为a[i]-b[i],但是爱丽丝选择后变成了a[i]-1-0;

因此爱丽丝选择i的影响为b[i]-1;(让得分变大)

我们考虑鲍勃的影响,如果鲍勃不选i那么原本对于这一项的值为a[i]-b[i],但是鲍勃选择后变成了

0-b[i]+1;

因此鲍勃选择i的影响为1-a[i];(让得分变小)

因此每个人选的总影响就应该为a[i]+b[i]-2,因此我们应该对a[i]+b[i]的值进行排序,然后从最大的一端开始选,然后输出结果即可

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define N 220000
  4. using namespace std;
  5. int a[N];
  6. int b[N];
  7. int sum[N];
  8. int n,t;
  9. bool cmp(int x,int y)
  10. {
  11. return a[x]+b[x]<a[y]+b[y];
  12. }
  13. signed main()
  14. {
  15. cin>>t;
  16. while(t--)
  17. {
  18. cin>>n;
  19. for(int i=1;i<=n;i++)
  20. {
  21. cin>>a[i];
  22. }
  23. for(int i=1;i<=n;i++)
  24. {
  25. cin>>b[i];
  26. }
  27. int ans=0;
  28. for(int i=1;i<=n;i++)
  29. {
  30. ans+=a[i]-b[i];
  31. sum[i]=i;
  32. }
  33. sort(sum+1,sum+1+n,cmp);
  34. for(int i=n;i>=1;i-=2)
  35. {
  36. ans+=b[sum[i]]-1;
  37. }
  38. for(int i=n-1;i>=1;i-=2)
  39. {
  40. ans-=a[sum[i]]-1;
  41. }
  42. cout<<ans<<"\n";
  43. }
  44. return 0;
  45. }

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/667644
推荐阅读
  

闽ICP备14008679号