ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Good Bye 2021

2021-12-31 21:02:09  阅读:200  来源: 互联网

标签:le int cin Codeforces 满足 Good solve Bye ldots


Good Bye 2021

A. Interger Diversity

题意

给定 \(n\) 个整数,你可以选择其中的任意项,使其变成它的相反数(如把 \(x\) 变成 \(-x\)) ,问操作后的序列中最多有多少个不同的数字。

分析

记录每个数字是否出现过,如果出现过而相反数没有出现过就把它变成相反数。

Code

/* 终点是一切概率的结束,也是一切期望的开始 */
#include <bits/stdc++.h>
using namespace std;

void solve()
{
    int n, res = 0; cin >> n;
    map<int, bool> ex;
    for (int i = 1; i <= n; i ++ )
    {
        int x; cin >> x;
        if (ex[x] && ex[-x]) continue;
        res ++ ;
        if (!ex[x]) ex[x] = true; else ex[-x] = true;
    }
    cout << res << endl;
}

signed main()
{
    cout.tie(0)->sync_with_stdio(0);
    int _; for (cin >> _; _--;) solve();
    return 0;
}

B. Mirror in the String

题意

给定长度为 \(n\) 的字符串 \(s_1s_2 \ldots s_n\) ,选择一个数字 \(k(1 \le k \le n)\) ,使其变成 \(s_1s_2 \ldots s_ks_ks_{k-1} \ldots s_1\) 。问操作后能得到的字符串的最小字典序为多少。

分析

  1. \(n = 1 \ or \ s_1 = s_2\)

    选择 \(k=1\) 即可得到字典序最小,因为选择 \(k(k \ge 2)\) 时,前两个字符依然是 \(s_1s_2\) ,后面又多了字符导致字典序不是最小。

  2. \(s1 \ != \ s2\)

    对于字符 \(s_i\) ,如果 \(s_{i+1} \gt s_i\) ,那么选择 \(k=i\) ,因为如果选择 \(k \gt i\) ,那么得到的字符串第 \(i+1\) 位一定变大了,就不是字典序最小。

Code

/* 终点是一切概率的结束,也是一切期望的开始 */
#include <bits/stdc++.h>
using namespace std;

void solve()
{
    int n; cin >> n;
    string s; cin >> s;
    if (n == 1 || s[0] == s[1]) return cout << s[0] << s[0] << endl, void();
    int p = 0;
    while(p < n - 1 && s[p + 1] <= s[p]) p ++ ;
    for (int i = 0; i <= p; i ++ ) cout << s[i];
    for (int i = p; i >= 0; i -- ) cout << s[i];
    cout << endl;
}

signed main()
{
    cout.tie(0)->sync_with_stdio(0);
    int _; for (cin >> _; _--;) solve();
    return 0;
}

C. Representative Edges

题意

给定长度为 \(n\) 的序列 \(a\) ,每次操作可以修改其中某一个元素的值,问最小操作多少次,使得对于任意 \(1 \le l \le r \le n\) ,满足 \(a_l + a_{l+1} + \ldots + a_r = \dfrac 1 2(a_l + a_r) \times (r - l + 1)\) 。

分析

可以发现题目要求的性质为等差数列的性质,题目变为:求最少修改多少次使得序列变为等差数列。

由于数据很小 \(1 \le n \le 70\) 。我们可以固定数列任意两项作为要求的等差数列的一部分,求出其他满足该等差数列性质的个数。

假设固定 \(i, j\) ,那么对于任意一项 \(k\) ,满足等差数列性质需要: $\dfrac {a_j - a_i} {j-i} = \dfrac {a_k - a_i} {k - i} $ ,即 \((a_j - a_i) \times (k - i) = (a_k - a_i) \times (j - i)\) 。

Code

/* 终点是一切概率的结束,也是一切期望的开始 */
#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = x; i <= y; i ++ )
using namespace std;
const int N = 1000, M = 400010, mod = 998244353, INF = 0x3f3f3f3f;

int a[N];

void solve()
{
    int n, ret; cin >> n; ret = max(0, n - 2);
    for (int i = 1; i <= n; i ++ ) cin >> a[i];
    rep(i, 1, n) rep(j, i + 1, n)
    {
        int save = 0;
        rep(k, 1, n) if ((a[k] - a[i]) * (j - i) == (a[j] - a[i]) * (k - i)) ++ save;
        ret = min(ret, n - save);
    }
    cout << ret << endl;
}

signed main()
{
    cout.tie(0)->sync_with_stdio(0);
    int _; for (cin >> _; _--;) solve();
    return 0;
}

D. Keep the Average High

题意

给定长度为 \(n\) 的序列 \(a\) ,选出最多的元素,满足对于任意 \(1\le l \lt r \le n\) (\(l, r\) 均指原序列的下标),满足以下至少一项:

  1. 存在至少一项 \(l \le k \le r\) 没有被选择。
  2. \(a_l + a_{l+1} \ldots a_r \ge x \times (r - l + 1)\) 。

问能够选择最多多少个元素。

分析

对于任意 \(l, r\) ,如果其中有一个没有被选择,那么一定满足限制,所以只需要考虑 \([l, r]\) 都被选择时是否满足限制。

注意第 \(2\) 个限制,等价于 \((a_l - x) + (a_{l + 1} - x) + \ldots + (a+r - x) \ge 0\) 。

注意到 \([l, r]\) 是连续的,我们设 \(p(i) = \sum_{i=1}^i a_i - x\) ,那么上述限制等价于 \(p(r) - p(l-1) \ge 0\) 。

假设目前枚举到第 \(i\) 位,那么我们需要考虑后两位,如果 \(p(i + 2) - p(i) \lt 0\) ,即 \(a(i+1) + a(i+2) \lt 0\) ,那么我们不能全部取到,否则令 \(l = i+1, r=i+2\) ,不满足限制。如果满足 \(p(i+2) - p(i) \ge 0\) ,因为前面满足的序列加上第 \(i+1\) 位不一定不小于 \(0\) ,那么我们取最大值,把 \(i+1\) 位放到待判断的序列中,即:
\(a_1 \ldots a_qq_{q+1} \ldots a_i \ldots a_n\) ,区间 \([q, i]\) 为满足限制的区间,而 \(i+1\) 进入到待选择区域。这样我们就不仅只考虑满足限制的最后一个位置后面的两个位置了。对于带选择区间 \([l, r]\) ,因为加上了 \(a_r\) 导致 \(p(r) - p(l-1) < 0\) ,那么只需要不选择 \(r\) 即可,因为 \([l, r-1]\) 加上前面满足的区间依然不小于零。

Code

/* 终点是一切概率的结束,也是一切期望的开始 */
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 200010;

int a[N], pre[N];

void solve()
{
    int n, x, ret, mx = 0; cin >> n; ret = n;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];
    cin >> x;
    for (int i = 1; i <= n; i ++ ) pre[i] = pre[i-1] + a[i] - x;
    for (int i = 2; i <= n; i ++ )
        if (pre[i] < mx) { -- ret; mx = pre[i]; ++ i; }
        else mx = max(mx, pre[i-1]);
    cout << ret << endl;
}

signed main()
{
    cout.tie(0)->sync_with_stdio(0);
    int _; for (cin >> _; _--;) solve();
    return 0;
}

标签:le,int,cin,Codeforces,满足,Good,solve,Bye,ldots
来源: https://www.cnblogs.com/Horb7/p/15754403.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有