codeforces 905 div.3(A - G2)

A. Morning

思路:将 0 0 0 替换成 10 10 10,然后遍历这字符串,用变量 p r e pre pre 维护上一个字符的值,最后求出总耗的时间

void solve()
{
    string s; cin >> s;
    int cnt = 0;
    int pre = 1;
    for (int i = 0; i < s.size(); i++) {
        int m = s[i] - '0';
        if (m == 0) m = 10;
        cnt += abs(m - pre);
        pre = m;
    }
    cout << cnt + 4 << endl;
}

写的时候思路有点乱,当时是将 0 0 0 特别判断,直接将 0 0 0 变成 10 10 10 就更加直观且方便


B. Chemistry

思路:当删成一个奇数长度和只有一个奇数字母的时候,如果要删掉的字母数量大于 k k k,那么则输出 " N O " "NO" "NO",否则输出 " Y E S " "YES" "YES"

void solve()
{
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    map<int, int> mp;
    for (int i = 0; i < s.size(); i++) {
        mp[s[i]-'a'] ++;//统计每个数的个数
    }
    int cnt = 0;
    for (auto x : mp) {
        if (x.second % 2 == 1)cnt++;//奇数个数的数量
    }
 
    int ans = 0;//奇数的话删到只剩一个,默认是删完ans个后的串是奇数串,此时剩一个奇数
    if (cnt > 1) ans = cnt - 1;//删掉只剩一个奇数
 
    if (ans > k) puts("NO");//
    else puts("YES");
}

C. Raspberries

思路:特判 k = = 4 k == 4 k==4 的时候,由于 k = = 4 k == 4 k==4 的因子可以有两个 2 2 2 组成,所以我们在遍历数组的时候同时要判断是否存在 2 2 2 的因子,存在两个的时候, k = = 4 k == 4 k==4 的最小操作数为 0 0 0

void solve()
{
  int n, k;
  cin >> n >> k;
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++)
  {
    cin >> a[i];
  }
  int ans = INF, cnt = 0;
  if (k == 4)
  {
    for (int i = 1; i <= n; i++)
    {
      if (a[i] % 2 == 0)
      {
        cnt++;
      }
      if (a[i] % k == 0)
      {
        ans = 0;
      }
      ans = min(ans, k - (a[i] % k));
    }
    if (cnt >= 2)
    {
      cout << 0 << endl;
    }
    else
    {
      cout << min(ans, 2 - cnt) << endl;
    }
  }
  else
  {
    for (int i = 1; i <= n; i++)
    {
      if (a[i] % k == 0)
      {
        ans = 0;
      }
      ans = min(ans, k - (a[i] % k));
    }

    cout << ans << endl;
  } 
}

D. In Love

思路:考察的是数据结构,对 m u l t i s e t multiset multiset 的熟练度,关于集合,能否保证集合群当中存在一组线段集合不想交,就看是否存在,右边界的集合最小和左边界的集合最大若是存在 r < l r < l r<l,即保证一直存在这个合法解

const int INF = 0x3f3f3f3f;
int b[N];
multiset<int> r;//右边边界最小
multiset<int, greater<int>> l;//左边边界最大
/*
 ---r----l----   即存在
*/
void solve()
{
    char c[2];
    int L, R;
    cin >> c >> L >> R;
    if (*c == '+') {
        l.insert(L);
        r.insert(R);
    }
    else {
        l.erase(l.find(L));
        r.erase(r.find(R));
    }
    if (l.empty() && r.empty()) {
        puts("NO");
    }
    else if (*l.begin() > *r.begin()) {
        puts("YES");
    }
    else {
        puts("NO");
    }
}

E. Look Back

思路:将改变大小的形式转换为 a i ∗ 2 x a_i * 2 ^x ai2x,维护相邻两个数的前缀 x x x,相邻两个数的大小谁能变得谁大谁小的操作数是固定的,同时将前面相邻的数的操作前缀进行相加即是当前两个相邻数的操作数,将所有的 x x x 相加即是答案。

void solve()
{
    int n; cin >> n;
    vector<int > a(n + 1);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    ll ans = 0,cnt= 0;
    for (int i = 1; i < n; i++) {
        int l = a[i - 1], r = a[i], ct = 0;
        while (l < r) ct--, l *= 2;
        while (l > r) ct++, r *= 2;
 
        cnt = max(0ll, cnt + ct);
        ans += cnt;
    }
    cout << ans << endl;
}

F. You Are So Beautiful

思路:要求只有一种方法选择一个序列,那么保证没有重复的,就需要找到数字出现的最后一个位置,数字最前出现的位置是这个子序列多一种情况下,后面再出现的情况是会出现重复。因此整个过程只考虑数字第一次出现的位置和最后一次出现的位置。(子序列不连续,但是题目要求的 l , r l,r l,r 的范围与长度一致,相当于找子串)

void solve()
{
    int n; cin >> n;
    vector<int > a(n + 1);
    map<int, int> f, e, mp;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        if (mp[a[i]] == 0) {
            mp[a[i]] = 1;
            f[a[i]] = i;
            e[a[i]] = i;
        }
        else {
            e[a[i]] = i;
        }
    }
    ll cnt = 0,ans = 0;
    for (int i = 0; i < n; i++) {
        if (f[a[i]] == i) {
            cnt++;
        }
        if(e[a[i]] == i) ans += cnt;
    }
    cout << ans << endl;
}

G2. Dances (Hard Version)

思路:给数组 a a a 排序,每个 a a a 都尽量选择满足要求的尽量小的 b b b ,然后可以发现如果加入的数字小于剩下的最大的数字,那么可以让答案加一,否则答案不变.

void solve()
{
    int n, m;
    cin >> n >> m;
    multiset<int> b;
    vector<int> a(n - 1);
    for (int i = 0; i < n - 1; i++) cin >> a[i];
    for (int i = 0; i < n; i++) {
        int x;  cin >> x;
        b.insert(x);
    }
 
    sort(a.begin(), a.end());
    int ans = 0;
    for (auto x : a) {
        auto it = b.upper_bound(x);
        if (it != b.end()) {
            b.erase(it);
            ans += 1;
        }
    }
    ll t = 1ll * ans * m;
    int mx = *prev(b.end());
    t += min(mx - 1, m);
 
    cout << 1ll * n * m - t << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值