Codeforces Round #744 (Div. 3)(补题)

本文介绍了五道算法竞赛题目,涉及字符串处理、排序、矩阵操作和数组优化等。A题检查字符串中字符平衡性,B题通过模拟实现排序,C题暴力判断矩阵中的特定符号,D题采用贪心策略解决会议配对,E题利用双端队列优化排列和数组。每道题都提供了清晰的解决方案和代码实现。
摘要由CSDN通过智能技术生成


题目链接

A.Casimir’s String Solitaire

Sol:判断b的数量是否等于a与c的和
Code:

#define ok() cout << "Yes\n" 
#define gg() cout << "No\n" 
void solve()
{
   string s;
   cin >> s;
   int a, b, c;
   a = b = c = 0;
   for(int i = 0; i < s.size(); ++i)
   {
       a += (s[i] == 'A');
       b += (s[i] == 'B');
       c += (s[i] == 'C');
   }
   if(b == a + c) ok();
   else gg();
}

B.Shifting Sort

Sol: n ≤ 50 n \le 50 n50,故可以暴力模拟,每次把最小的放在前面。
Code:

const int N = 100;
int a[N];
void solve()
{
   int n;
   cin >> n;
 
   rep(i, 1, n ){
       cin >> a[i];
   }
   map<PII, int> ans;
   for(int i = 1; i <= n ; ++i)
   {
       int id = i, mi = a[i];
       for(int j = i + 1; j <= n; ++j)
       {
           if(a[j] < mi) 
           {
               id = j;
               mi = a[j];
           }
       }
       int tt = id - i;
       if(tt) 
       {
           ans[{i, n}] = tt;
           while(tt -- ) {
                int pre = a[i];
                for(int j = i; j < n; ++j)
                {
                    a[j] = a[j + 1];
                }
                a[n] = pre; 
            }
       }
   }
   cout << ans.size() << endl;
   for(auto &it : ans)
   {
       cout << it.first.first << " " << it.first.second << " " << it.second << endl;
   }
}

C. Ticks

Sol: n , m ≤ 10 n,m \le 10 n,m10, 依旧暴力判断。。
Code:

void solve()
{
    int n, m, k;
    cin >> n >> m >> k;
    string s[n];
    rep(i, 0, n - 1) cin >> s[i];
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++ j)
        {
            if(s[i][j] == '*') {
                int d = 0;
                while( i-d > 0 && j + d +1< m && j - d > 0 && s[i-d-1][j-d-1] != '.' && s[i-d-1][j+d+1] != '.')
                    ++ d;
                if(d >= k) {
                    s[i][j] = '+';
                    for(int h = 1; h <= d; ++h)
                    {
                        s[i-h][j+h] = '+';
                        s[i-h][j-h] = '+';
                    }
                }    
            }
        }
    bool ok = true;
    for(int i = 0;i < n; ++i)
        for(int j = 0; j < m; ++j)
            if(s[i][j] == '*')
                ok = false;
    if(ok) ok();
    else gg();
 
}

D.roductive Meeting

Sol: 贪心, 将所有不为零的放入大根堆,每次取出两个作为一对。

Code:

void solve()
{
   int n;
   cin >> n;
   PII a[n + 1];
   priority_queue<PII>q;
   while(q.size()) q.pop();
   rep(i, 1, n) {
       cin >> a[i].first;
       a[i].second = i;
       if(a[i].first != 0) q.push(a[i]);
   }
   vector<PII>ans;
   while(q.size() >= 2)
   {
       PII p = q.top(); q.pop();
       PII y = q.top(); q.pop();
       ans.push_back({p.second, y.second});
       if(p.first > 1) q.push({p.first - 1, p.second});
       if(y.first > 1) q.push({y.first - 1, y.second});
   }
   cout << ans.size() << endl;
   for(auto &it : ans)
    cout << it.first << " " << it.second << endl;
}

E1.Permutation Minimization by Deque

Sol: 利用deque,大的放后面,小的放前面。
Code:

void solve()
{
   int n;
   deque<int>q;
   cin >> n;
   VI a(n);
   for(auto &x : a) cin >> x;
   for(auto &x : a){
       if(q.size() == 0) q.push_back(x);
       else {
           int st = q.front();
           if(x <= st) q.push_front(x);
           else q.push_back(x);
       }
   }
   while(q.size()) cout << q.front() << " ", q.pop_front();
   br;
}

E2.Array Optimization by Deque

Sol:
两种情况:

  • 放前面,答案为后面比这个数小的个数。
  • 放后面,答案为前面比这个数大的个数
    首先离散化,利用树状数组动态维护区间数的个数。
    Code:
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
 
const int N = 1000010;
 
int n;
int tr[N];
int a[N];
int lowbit(int x){
    return x & -x;
}
 
void add(int x, int c) {
    for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
 
int sum(int x){
    int res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}
 
void solve()
{
    memset(tr, 0, sizeof tr);
    scanf("%lld", &n);
    vector<int>all;
    for(int i = 1; i <= n; ++i)
    {
        scanf("%lld", &a[i]);
        
        all.push_back(a[i]);
    }
    // 离散化
    sort(all.begin(), all.end());
    all.erase(unique(all.begin(), all.end()), all.end());
    for(int i = 1; i <= n; ++i) a[i] = lower_bound(all.begin(), all.end(), a[i]) - all.begin() + 1;// +1防止出现负数下标
    int ans = 0;
    for(int i = 1; i <= n; ++ i)
    {
        int hh = sum(a[i] - 1), tt = sum(n) - sum(a[i]);
        if(hh <= tt) {
            ans += hh;
        }
        else ans += tt;
        add(a[i], 1);
    }
    cout << ans << endl;
}
 
signed main()
{
    int tt; scanf("%lld", &tt);
    while(tt -- ) solve();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W⁡angduoyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值