当前位置:   article > 正文

Codeforces Round 919 (Div. 2) A - C 题解

Codeforces Round 919 (Div. 2) A - C 题解

A. Satisfying Constraints

题意:给你n个条件,给你两个数字a和x,如果a数字是1,让目标数字k>=x。如果a数字是2,让目标数字k<= x。如果a数字是3,让目标数字k!=x 。最后求出有多少数字符合条件。
题解:n很小,有很多种方法来做。我说一下我自己的吧,设两个边缘,一个Max , 一个Min。控制好边缘以后将a == 3的数字存入数组,然后排序,看看其中多少个数字Min <= k <= Max里,统计相减即可,有很多细节在代码里。
代码:
  1. #include<bits/stdc++.h>
  2. using namespace std ;
  3. typedef long long ll ;
  4. const int maxn = 1e6 + 7 ;
  5. inline ll read(){
  6. ll x = 0 , f = 1;
  7. char c = getchar() ;
  8. while(c > '9' || c < '0'){
  9. if(c == '-')
  10. f = -1 ;
  11. c = getchar() ;
  12. }
  13. while(c >= '0' && c <= '9'){
  14. x = x * 10 + c - '0' ;
  15. c = getchar() ;
  16. }
  17. return x * f ;
  18. }
  19. ll t , n , m , a[maxn] , b[maxn] ;
  20. void solve(){
  21. n = read() ;
  22. map < ll , ll > mp ;
  23. ll minn = 1 , maxx = 1e9 , cnt = 0 ;
  24. for(int i = 1 ; i <= n ; i ++){
  25. ll u , v ;
  26. u = read() ;
  27. v = read() ;
  28. if(u == 1){
  29. minn = max(minn , v) ;
  30. }
  31. if(u == 2){
  32. maxx = min(maxx , v) ;
  33. }
  34. if(u == 3){
  35. b[++ cnt] = v ;
  36. }
  37. }
  38. if(minn > maxx){
  39. cout << 0 << endl ;
  40. return ;
  41. }
  42. sort(b + 1 , b + cnt + 1) ;
  43. ll rt = -1 , Rt = -1 ;
  44. for(int i = 1 ; i <= cnt ; i ++){
  45. if(b[i] >= minn){
  46. rt = i ;
  47. break ;
  48. }
  49. }
  50. for(int i = cnt ; i >= 1 ; i --){
  51. if(b[i] <= maxx){
  52. Rt = i ;
  53. break ;
  54. }
  55. }
  56. if(rt == -1 || Rt == -1){
  57. cout << maxx - minn + 1 << endl ;
  58. return ;
  59. }
  60. else{
  61. cout << maxx - minn + 1 - (Rt - rt + 1) << endl ;
  62. return ;
  63. }
  64. }
  65. int main(){
  66. t = read() ;
  67. while(t --){
  68. solve() ;
  69. }
  70. return 0 ;
  71. }

B. Summation Game

题意:给你n个数字,还有一个k一个x。有两个人,Alice和Bob。Alice最多可以删除k个数字,Bod最多可以将x个数字变成他的相反数。Alice想让结果最大,Bob想让最后的数字和尽量的小,两个人都用最优的策略。求最后的答案是多少。
题解:首先看Bob的操作,因为所有的数字都大于0,所以肯定是将更多的数字变成相反数答案会变到最小。那这个题就迎刃而解了,枚举x(1<=x<=k) ,所有答案取最小值即可,当然需要用前缀和优化。
代码:
  1. #include<bits/stdc++.h>
  2. using namespace std ;
  3. typedef long long ll ;
  4. const int maxn = 1e6 + 7 ;
  5. inline ll read(){
  6. ll x = 0 , f = 1;
  7. char c = getchar() ;
  8. while(c > '9' || c < '0'){
  9. if(c == '-')
  10. f = -1 ;
  11. c = getchar() ;
  12. }
  13. while(c >= '0' && c <= '9'){
  14. x = x * 10 + c - '0' ;
  15. c = getchar() ;
  16. }
  17. return x * f ;
  18. }
  19. ll t , n , m , k , a[maxn] , sum[maxn] , s[maxn] ;
  20. void solve(){
  21. n = read() ;
  22. m = read() ;
  23. k = read() ;
  24. for(int i = 1 ; i <= n ; i ++){
  25. a[i] = read() ;
  26. }
  27. sort(a + 1 , a + n + 1) ;
  28. for(int i = 1 ; i <= n ; i ++){
  29. sum[i] = sum[i - 1] + a[i] ;
  30. s[i] = s[i - 1] - a[i] ;
  31. }
  32. ll ans = -LONG_LONG_MAX ;
  33. for(int i = n ; i >= n - m ; i --){
  34. ll res = sum[i] ;
  35. res += (s[i] - s[max(i - k , 0ll)]) * 2 ;
  36. ans = max(ans , res) ;
  37. }
  38. cout << ans << endl ;
  39. }
  40. int main(){
  41. t = read() ;
  42. while(t --){
  43. solve() ;
  44. }
  45. return 0 ;
  46. }

C. Partitioning the Array

题意:给你n个数字,你可以枚举k,将n个数字切成n / k段数字段,k必须是n的因子,看看能否有一个m(m>=2),将n/k段数字所有变成一样的。查询一共有多少个答案。
题解:一开始我想错了,想的是奇偶性,交了之后发现不对,想到了用gcd,很明显,分成n/k段之后,每段数字相对应的数字(1<=i<=k)的差的gcd必须大于1才能成立。那这道题就很简单了。复杂度O(nlogn)
代码:
  1. #include<bits/stdc++.h>
  2. using namespace std ;
  3. typedef long long ll ;
  4. typedef pair < ll , ll > PII ;
  5. const int maxn = 1e6 + 7 ;
  6. inline ll read(){
  7. ll x = 0 , f = 1;
  8. char c = getchar() ;
  9. while(c > '9' || c < '0'){
  10. if(c == '-')
  11. f = -1 ;
  12. c = getchar() ;
  13. }
  14. while(c >= '0' && c <= '9'){
  15. x = x * 10 + c - '0' ;
  16. c = getchar() ;
  17. }
  18. return x * f ;
  19. }
  20. ll t , n , m , k , a[maxn] , b[maxn] , sum[maxn] , ji[maxn] , ou[maxn] ;
  21. vector < PII > q ;
  22. vector < ll > p ;
  23. void solve(){
  24. n = read() ;
  25. for(ll i = 0 ; i <= n + 100 ; i ++){
  26. ji[i] = ou[i] = 0 ;
  27. }
  28. ll cnt = 0 , ans = 0 ;
  29. for(ll i = 1 ; i <= (ll)(sqrt(n)) ; i ++){
  30. if(n % i == 0){
  31. if(i == n / i){
  32. b[++ cnt] = i ;
  33. }
  34. else{
  35. b[++ cnt] = i ;
  36. b[++ cnt] = n / i ;
  37. }
  38. }
  39. }
  40. sort(b + 1 , b + cnt + 1) ;
  41. for(int i = 1 ; i <= n ; i ++){
  42. a[i] = read() ;
  43. }
  44. for(int i = 1 ; i <= cnt ; i ++){
  45. ll gg = 0 ;
  46. for(int j = 1 ; j <= b[i] ; j ++){
  47. p.clear() ;
  48. for(int k = j ; k <= n ; k += b[i]){
  49. p.push_back(a[k]) ;
  50. }
  51. sort(p.begin() , p.end()) ;
  52. for(int i = 1 ; i < (int)p.size() ; i ++){
  53. gg = __gcd(gg , p[i] - p[i - 1]) ;
  54. }
  55. }
  56. if(gg != 1){
  57. ans ++ ;
  58. }
  59. }
  60. cout << ans << endl ;
  61. }
  62. int main(){
  63. t = read() ;
  64. while(t --){
  65. solve() ;
  66. }
  67. return 0 ;
  68. }
总结下来这场比赛打的并不理想,可以发现关于将所有数字变成一样类似的题,都可以用gcd来解,或者是奇偶性。

喜欢作者的记得点赞收藏加关注哦~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/55143
推荐阅读
相关标签
  

闽ICP备14008679号