Codeforces Round #576 (Div. 2) 题解

比赛链接https://codeforc.es/contest/1199
 
A. City Day
题意:给出一个数列,和俩个整数\(x,y\),要求找到序号最靠前的数字\(d\),使得\(d\)满足\(a_d<a_j\) (\(d-x\leq j<d\) && \(d<j\leq d+y\))。

分析:由于x和y都小于7,所以直接暴力即可。

AC代码:

#include <bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
ll n, x, y, a[SIZE];
int main() {
    io();
    cin >> n >> x >> y;
    rep(i, 1, n) cin >> a[i];
    rep(i, 1, n) {
        bool flag = 1;
        for (int k = i - 1, cnt = 1; k > 0 && cnt <= x; k--, cnt++) {
            if (a[k] <= a[i]) { flag = 0; break; }
        }
        for (int k = i + 1, cnt = 1; k <= n && cnt <= y; k++, cnt++) {
            if (a[k] <= a[i]) { flag = 0; break; }
        }
        if (flag) { cout << i << endl; return 0; }
    }
}

 
B. Water Lily

分析:几何水题,推个方程就好。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int main() {
    double l, h;
    cin >> h >> l;
    double s = (l * l - h * h) / 2 / h;;
    printf("%.12lf", s);
}

 
C. MP3
题意:一个数组中如果有\(K\)种不同的数,每个数的占用空间是\(k=log_2K\),这组数总内存是\(nk\),你有一个改变数的大小的能力,小于\(l\)可以改成\(l\)大于\(r\)可以改成\(r\),现在给出总内存,求最少改变次数。

分析:先求出最多能存\(k\)个数,然后我们显然用\(map\)来记录数据,然后把\(map\)中的前\(k\)个数和后k个数丢进一个双向队列(因为我们至少删除\(k\)个数,而这\(k\)个数只能在首或尾),对这\(2k\)个数求前缀和,在每k个数中求出最小值。

AC代码:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define SIZE 400007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
ll n, I, a[SIZE], pre[SIZE];
map<ll, ll> mp;
deque<pair<ll, ll> > q;
int main() {
    io(); cin >> n >> I;
    rep(i, 1, n) {
        cin >> a[i];
        ++mp[a[i]];
    }
    ll k = 0; I *= 8;   //用k记录最多存储几个数
    while (1ll * ceil(log2(mp.size() - k))* n > I) k++;
    auto it = mp.begin();
    auto itr = mp.rbegin();
    rep(i, 1, k) {
        q.push_back(make_pair(it->first, it->second));
        q.push_front(make_pair(itr->first, itr->second));
        it++, itr++;
    }
    auto itx = q.begin();
    rep(i, 1, q.size()) pre[i] = pre[i - 1] + itx++->second;
    ll sum = INF;
    rep(i, k, 2 * k) sum = min(sum, pre[i] - pre[i - k]);
    cout << sum;
}

 
D. Welfare State
题意:给定一个\(n\)个数的数列和两种操作。操作一是把序号为\(p\)的数字修改为\(x\),操作二是把所有小于\(x\)的数字修改为\(x\)。输出最终的数列。

分析:乍一看像线段树,但是会\(T\)(别问我怎么知道的),实际上直接乱搞就过了。我们发现对于第一种操作和第二种操作我们只需要考虑较大的那种,因此开两个数组,\(b\)数组保存操作一,\(maxx\)数组保存操作二,最后取\(max\)输出即可。

AC代码:

#include<bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
ll n, m, a[SIZE], b[SIZE], sig, maxx[SIZE], pos;
int main() {
    io(); cin >> n;
    rep(i, 1, n) cin >> a[i];
    cin >> m;
    rep(i, 1, m) {
        cin >> sig;
        if (sig == 1) {
            cin >> pos;
            cin >> a[pos];
            b[pos] = i;
        }
        else cin >> maxx[i];
    }
    for (int i = m; i; --i) maxx[i - 1] = max(maxx[i - 1], maxx[i]);
    rep(i, 1, n) cout << max(a[i], maxx[b[i]]) << ' ';
}

 
E. Matching vs Independent Set
题意:

猜你喜欢

转载自www.cnblogs.com/st1vdy/p/11273191.html