Codeforces Round 918 (Div. 4) 题解 | JorbanS

文章展示了五个C++编程题目,涉及整数比较、拉丁方阵、平方计算、自然语言处理、浪漫眼镜问题以及区间贡献计算。代码展示了不同的算法策略,如条件判断、循环遍历、排序和数据结构的使用。
摘要由CSDN通过智能技术生成

A - Odd One Out

int solve() {
    int a, b, c; cin >> a >> b >> c;
    if (a == b) return c;
    if (a == c) return b;
    return a;
}

B - Not Quite Latin Square

char solve() {
    int sum = ('A' + 'B' + 'C') * 3 + '?';
    for (int i = 0; i < 3; i ++) {
        cin >> s[i];
        for (int j = 0; j < 3; j ++) sum -= s[i][j];
    }
    return (char)sum;
}

C - Can I Square?

string solve() {
    cin >> n;
    ll res = 0;
    for (int i = 0; i < n; i ++) {
        int x; cin >> x;
        res += x;
    }
    ll x = sqrt(res);
    return x * x == res ? yes : no;
}

D - Unnatural Language Processing

void solve() {
    cin >> n >> s;
    for (int i = 0; i < n; i ++) {
        cout << s[i];
        if (i + 2 < n && (s[i + 2] == 'a' || s[i + 2] == 'e')) cout << '.';
    }
    cout << endl;
}

E - Romantic Glasses

int n, m;
int a[N];
ll pre[N];

string solve() {
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        pre[i] = pre[i - 1] + a[i] * pow(-1, i & 1);
    }
    map<ll, bool> mp;
    mp[0] = true;
    for (int i = 1; i <= n; i ++) {
        if (mp[pre[i]]) return yes;
        else mp[pre[i]] = true;
    }
    return no;
}

F - Greetings

可以发现只有下列情况计算一次贡献,即区间包含关系

L[        ]R
  l[  ]r

法一:树状数组,每次在 L < l L<l L<l 的集合中查询,有多少个 R > r R>r R>r

int n, m;
int l;
pii a[N];
int b[N];
int tr[N];

inline int lowbit(int x) { return x & -x; }

void update(int x, int k = 1) {
    while (x <= l) {
        tr[x] += k;
        x += lowbit(x);
    }
}

int query(int x) {
    int res = 0;
    while (x) {
        res += tr[x];
        x -= lowbit(x);
    }
    return res;
}

ll solve() {
    cin >> n;
    for (int i = 0; i < n; i ++) {
        cin >> a[i].aa >> a[i].bb;
        b[i] = a[i].bb;
    }
    sort(a, a + n);
    sort(b, b + n);
    l = unique(b, b + n) - b;
    for (int i = 0; i <= l; i ++) tr[i] = 0;
    ll res = 0;
    for (int i = 0; i < n; i ++) {
        int x = lower_bound(b, b + n, a[i].bb) - b;
        res += query(l - x);
        update(l - x);
    }
    return res;
}

法二:用 vectorerase 函数,奇怪的是复杂度为 O ( n 2 ) O(n^2) O(n2),竟然过了

int n, m;
pii a[N];
int b[N];

ll solve() {
    cin >> n;
    vector<int> b;
    for (int i = 0; i < n; i ++) {
        cin >> a[i].aa >> a[i].bb;
        b.push_back(a[i].bb);
    }
    sort(a, a + n);
    sort(b.begin(), b.end());
    ll res = 0;
    for (int i = 0; i < n; i ++) {
        auto it = lower_bound(b.begin(), b.end(), a[i].bb);
        res += it - b.begin();
        b.erase(it);
    }
    return res;
}

法三:排序使得 a i < a j a_i\lt a_j ai<aj,只要统计 b i > a j b_i\gt a_j bi>aj 的数量,归并排序统计逆序对

ai[        ]aj
  bi[  ]bj
int n, m;
pii a[N];
int q[N], t[N];
ll res = 0;

void mergeSort(int l, int r) {
    if (l == r) return;
    int mid = l + r >> 1;
    mergeSort(l, mid), mergeSort(mid + 1, r);
    int i = l, j = mid + 1, k = 0;
    while (i <= mid && j <= r) {
        if (q[i] <= q[j]) t[k ++] = q[i ++];
        else {
            res += mid - i + 1;
            t[k ++] = q[j ++];
        }
    }
    while (i <= mid) t[k ++] = q[i ++];
    while (j <= r) t[k ++] = q[j ++];
    for (int i = l, k = 0; i <= r; i ++, k ++) q[i] = t[k];
}

ll solve() {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i].aa >> a[i].bb;
    sort(a, a + n);
    for (int i = 0; i < n; i ++) q[i] = a[i].bb;
    res = 0;
    mergeSort(0, n - 1);
    return res;
}
  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JorbanS

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

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

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

打赏作者

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

抵扣说明:

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

余额充值