Educational Codeforces Round 100 (Rated for Div. 2)

Educational Codeforces Round 100 (Rated for Div. 2)

A - Dungeon

贪心

int main() {
    IOS;
    for (cin >> _; _; --_) {
        ll a, b, c; cin >> a >> b >> c;
        ll d = (a + b + c) / 9 * 9;
        if (d != a + b + c) cout << "NO
";
        else if (d / 9 > min(min(a, b), c)) cout << "NO
";
        else cout << "YES
";
    }
    return 0;
}

B - Find The Array

每个b只含有一个二进制下的1, 必定相互之间可整除, 选择最接近 a[i] 的2的阶乘即可

或者还有一种解法 $a_1, 1, a_3, 1, ..., $ or (1, a_2, 1, a_4, ...) 这两个数组中必定有一个满足

ll solve(int x) {
    ll m = 1e12, ans = -1;
    rep (i , 0 , 29) {
        ll b = 1ll << i;
        if (abs(b - x) < m) m = abs(b - x), ans = b;
    }
    return ans;
}
 
int main() {
    IOS;
    for(cin >> _; _; --_) {
        cin >> n ;
        rep (i, 1, n) cin >> a[i];
        rep (i, 1, n) cout << solve(a[i]) << " "; cout << '
';
    }
    return 0 ;
}

C - Busy Robot

模拟完事

int main() {
    IOS; 
    for (cin >> _; _; --_) {
        cin>>n;;
        rep (i, 1, n) cin >> t[i] >> pos[i];
        t[n + 1] = 2e18;
        ll R = 1,nowpos = 0, nowt = 1, ans = 0;
        for (ll L = 1; L <= n; L = R) {
            nowt = t[L]; R = L + 1;
            while (R <= n && t[R] < nowt + abs(nowpos - pos[L])) {
                ll tmp;
                if (nowpos < pos[L]) tmp = nowt + (pos[R] - nowpos);
                else tmp = nowt - (pos[R] - nowpos);
                if (tmp >= t[R] && tmp <= min(nowt + abs(nowpos - pos[L]), t[R+1])) ++ans;
                ++R;
            }
            if (R == L + 1) ++ans;
            nowpos = pos[L];
        }
        cout<< ans <<'
';
    }
    return 0;
}

D - Pairs

先把给定的b序列排个序, 再从未选的集合里找能配对的数量(配n-x的, 和x的数量)

然后得出可以属于 x, 可以属于 n - x 的数量 ansl, ansr,

想想小学题, 全班n个人, a个会乒乓, b个会足球, 问多少人两个都会

这题是有 n 个数(b数组), ansl可以属于 x 对, ansr可以属于 n - x那一堆, 问多少个数可以属于二者

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; rep (i, 1, n) cin >> a[i], v[a[i]] = 1;
        int cnt = 0, ansl = 0, ansr = 0; sort(a + 1, a + n + 1);
        rep (i, 1, n << 1) if(!v[i]) b[++cnt] = i, s.insert(i);
        rep (i, 1, n) {
            auto it = s.upper_bound(a[i]);
            if (it == s.end()) continue;
            else s.erase(it), ++ansl;
        }
        set<int>().swap(s);
        rep (i, 1, n) s.insert(b[i]);
        rep (i, 1, n) {
            auto it = s.lower_bound(a[i]); 
            if (it == s.begin()) continue;
            else s.erase(--it), ++ansr;
        }
        set<int>().swap(s);
        rep (i, 1, n) v[a[i]] = 0;
        cout << abs(ansl + ansr - n) + 1 << '
';
    }
    return 0;
}

E - Plan of Lectures

这一眼就是拓扑排序, 关键是如何处理那 k 对数, 带权并查集不就好了?

int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
 
void unit(int x, int y) {
    x = find(x);
    if (x == y) return;
    f[y] = x; sz[x] += sz[y]; ed[x] = ed[y];
}
 
int main() {
    IOS; cin >> n >> k; vector<VI>(n + 1).swap(h);
    rep(i, 0, n) f[i] = ed[i] = i;
    rep(i, 1, n) {
        cin >> a[i]; if (!a[i]) continue;
        if (a[i] == i) return cout << 0, 0;
        h[a[i]].pb(i); ++sz[i];
    }
    rep(i, 1, k) {
        int a, b; cin >> a >> b;
        if (ne[a] || pre[b]) return cout << 0, 0;
        int nx = find(a), ny = find(b);
        if (nx == ny) return cout << 0, 0;
        ne[a] = b; pre[b] = a; unit(a, b);
    }
    rep(i, 1, n) if (f[i] == i) {
        for (int j = i; j; j = ne[j]) {
            int x = find(a[j]);
            if (x == i) return cout << 0, 0;
            for (auto y : h[j]) {
                int fy = find(y);
                if (fy == i) --sz[i], a[y] = 0;
            }
        }
    }
    queue<int> q; int ls = 0;
    rep(i, 1, n) if (f[i] == i && !sz[i]) q.push(i);
    while (!q.empty()) {
        int x = q.front(); q.pop();
        if (pre[x] || ne[ls]) return cout << 0, 0;
        pre[x] = ls; ne[ls] = x; ls = ed[x];
        for (int i = x; i; i = ne[i]) for (auto y : h[i]) {
            y = find(y);
            if (y != x && --sz[y] == 0) q.push(y);
        }
    }
    int cnt = 0;
    for (int i = ne[0]; i; i = ne[i]) ++cnt;
    if (cnt != n) return cout << 0, 0;
    for (int i = ne[0]; i; i = ne[i]) cout << i << ' ';
    return 0;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/14156634.html