码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #636 (Div 3) 题解

时间:2020-04-25 10:30:47      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:ems   ret   strong   需要   ORC   def   ref   就是   cin   

A Candies

题目链接

观察这个式子左边,这玩意就等于 \(x(2^k-1)\)。于是我们枚举所有的 \(2^k-1\),看看是否存在 \(x\) 即可。

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 using namespace std;
 
 int T, n;
 int a[] = { 0, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823 };
 
 int main()
 {
     cin >> T;
     while(T--)
     {
         cin >> n;
         for(int i = 1; i < 30; i++)
             if(n % a[i] == 0)
             {
                 printf("%d\n", n / a[i]);
                 break;
             }
     }
     return 0;
 }

B Balanced Array

题目链接

先说说不合法的情况——\(n/2\) 是奇数:因为奇数个奇数是奇数,奇数个偶数是偶数,所以两边不可能相等。

偶数部分按照类似 \(2,4,6,8...\) 这样随便构造,奇数部分的前面 \(=\) 偶数部分对应数 \(-1\),最后一个再把和变成一样的。

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 using namespace std;
 
 int T, n, sum1, sum2, a[1000000];
 
 int main()
 {
     scanf("%d", &T);
     while(T--)
     {
         scanf("%d", &n);
         if((n / 2) % 2 != 0) { printf("NO\n"); continue; }
         printf("YES\n");
         a[0] = sum1 = sum2 = 0;
         for(int i = 1; i <= n / 2; i++) a[i] = a[i - 1] + 2, sum1 += a[i];
         for(int i = n / 2 + 1; i < n; i++) a[i] = a[i - n / 2] - 1, sum2 += a[i]; 
         a[n] = sum1 - sum2;
         for(int i = 1; i <= n; i++) printf("%d ", a[i]);
         printf("\n");
     }
     return 0;
 }

C Alternating Subsequence

题目链接

如果把连续的正数算作一组,连续的负数算作一组,题面就是要求在每一组中选出一个数,使和最大。那么只要在每一组里面取出一个最大数加到答案里即可。

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 using namespace std;
 
 long long T, n, ans = 0, max_, a[1000000];
 
 int main()
 {
     scanf("%lld", &T);
     while(T--)
     {
         scanf("%lld", &n);
         max_ = ans = a[0] = 0;
         for(int i = 1; i <= n; i++)
         {
             scanf("%lld", &a[i]);
             if(a[i] < 0 && a[i - 1] > 0 || a[i] > 0 && a[i - 1] < 0 || i == 1)
             {
                 ans += max_;
                 max_ = a[i];
             }
             else max_ = max(max_, a[i]);
         }
         ans += max_;
         printf("%lld\n", ans);
     }
     return 0;
 }

D Constant Palindrome Sum

题目链接

先枚举 \(x\)。如果把 \(a[i]\)\(a[n-i+1]\) 算作一组,每一组都有 \(3\) 种情况:不需要改/改一个数/改两个数。

\(1.\) 预处理 \(cnt[i]\) 表示和本来就等于 \(i\) 的有几组,那么就有 \(cnt[x]\) 组根本不需要改。

\(2.\) 大部分只需要改一个。若两个数分别为 \(x_0,x_1\),只要把 \(x_0\) 改为 \(x-x_1\) 或把 \(x_1\) 改为 \(x-x_0\) 即可。

\(3.\)\(x_0 >= x\) && \(x_1 >= x\)\(x-x_0 > k\) && \(x - x_1 > k\),这种需要两个数都改。

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 using namespace std;
  
 const int N = 2333333;
 int T, n, k, ans = 0x3f3f3f3f, a[N], cnt[N], b[N], sum1[N], sum2[N], c[N];
  
 int main()
 {
     scanf("%d", &T);
     while(T--)
     {
         scanf("%d%d", &n, &k);
         for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
         for(int i = 1; i <= n / 2; i++)
         {
             cnt[a[i] + a[n - i + 1]]++;
             b[max(a[i], a[n - i + 1])]++;
             c[min(a[i], a[n - i + 1])]++;
         }
         sum1[0] = sum2[2 * k + 1] = 0;
         for(int i = 1; i <= 2 * k; i++) sum1[i] = sum1[i - 1] + b[i];
         for(int i = 2 * k; i > 0; i--) sum2[i] = sum2[i + 1] + c[i];
         for(int i = 1; i <= 2 * k; i++)
         {
             if(i > k) ans = min(ans, n / 2 - cnt[i] + sum1[i - k - 1]);
             else ans = min(ans, n / 2 - cnt[i] + sum2[i]);
         }
         printf("%d\n", ans);
         for(int i = 1; i <= n / 2; i++)
         {
             cnt[a[i] + a[n - i + 1]] = 0;
             b[max(a[i], a[n - i + 1])] = 0;
             c[min(a[i], a[n - i + 1])] = 0;
         }
         ans = 0x3f3f3f3f;
     }
     return 0;
 }

E Weights Distributing

题目链接

一道可爱的图论题~

首先肯定不需要真的先去构造边权再跑最短路,而是应该设计一种走法,按照一定方式加入边权,使权值最小。

这个“一定方式”很简单:从小到大把边权安排在 走过的路上,至于那些没走过的,我们不关心。

Codeforces Round #636 (Div 3) 题解

标签:ems   ret   strong   需要   ORC   def   ref   就是   cin   

原文地址:https://www.cnblogs.com/Andy-park/p/12771674.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!