Educational Codeforces Round 72 (Rated for Div. 2)

Posted hankeke

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 72 (Rated for Div. 2)相关的知识,希望对你有一定的参考价值。

又垫底了。

和上一场一样,因为 D 题写错了一个小地方,把时间全部耗在上面了。

(还不是水平问题,要是能想到 D 题的最优解法,也就不存在这种问题了。

A. Creating a Character

[ str + x > int + epx - x ]

[ 2x>int+epx-str ]

#include<bits/stdc++.h>
 
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
 
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
 
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
 
template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}
 
int str, it, ex;
 
inline void work() {
    int p = it - str + ex;
    if (p < 0) printf("%d
", ex + 1);
    else printf("%d
", std::max(0, ex - p / 2));
}
 
inline void init() {
    read(str), read(it), read(ex);
}
 
int main() {
    #ifdef hzhkk
//  freopen("hkk.in", "r", stdin);
    #endif
    int T;
    read(T);
    while (T--) {
        init();
        work();
    }
    fclose(stdin), fclose(stdout);
    return 0;
}

B. Zmei Gorynich

(a = max d_i)(b = max d_i - h_i)

如果能直接用 (a) 杀掉就是 (1)

否则如果 (b leq 0) 那么无解。

不然就一直用 (b) 直到可以用 (a) 干掉。

#include<bits/stdc++.h>
 
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
 
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
 
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
 
template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}
 
const int N = 100 + 7;
 
int n, m, hh1, hh2;
int d[N], h[N];
 
inline void work() {
    if (m > hh1 && hh2 == 0) {
        puts("-1");
        return;
    }
    if (m > hh1) printf("%d
", (m - hh1 - 1) / hh2 + 2);
    else puts("1");
}
 
inline void init() {
    read(n), read(m);
    hh1 = hh2 = 0;
    for (int i = 1; i <= n; ++i) {
        read(d[i]), read(h[i]);
        smax(hh1, d[i]);
        smax(hh2, d[i] - h[i]);
    }
}
 
int main() {
    #ifdef hzhkk
//  freopen("hkk.in", "r", stdin);
    #endif
    int T;
    read(T);
    while (T--) {
        init();
        work();
    }
    fclose(stdin), fclose(stdout);
    return 0;
}

C. The Number Of Good Substrings

显然如果满足条件的 (01) 串,最高位的 (1) 不会在 (18) 位以上。

所以直接暴力。

#include<bits/stdc++.h>
 
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
 
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
 
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
 
template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}
 
const int N = 2e5 + 7;
 
int n;
int f[N];
char s[N];
 
inline void work() {
    for (int i = 1; i <= n; ++i)
        if (s[i] == '1') f[i] = 0;
        else if (s[i - 1] != '0' && s[i] == '0') f[i] = 1;
        else f[i] = f[i - 1] + 1;
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        int now = 0;
        for (int j = 0; j <= 18 && j < i; ++j) {
            if (s[i - j] == '1') now += 1 << j;
            if (now == j + 1) ++ans;
        }
        if (i > 19 && now > 19 && now <= f[i - 19] + 19) ++ans;
//      dbg("i = %d, ans = %d
", i, ans);
    }
    printf("%d
", ans);
}
 
inline void init() {
    scanf("%s", s + 1);
    n = strlen(s + 1);
}
 
int main() {
    #ifdef hzhkk
//  freopen("hkk.in", "r", stdin);
    #endif
    int T;
    read(T);
    while (T--) {
        init();
        work();
    }
    fclose(stdin), fclose(stdout);
    return 0;
}

D. Coloring Edges

题意等价于由同色的边构成的子图是一个 (DAG)

所以如果图中存在环,那么就把由编号小的点指向编号大的点的边颜色记为 (1),反之为 (0)

#include<bits/stdc++.h>
 
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
 
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
 
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
 
template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}
 
const int N = 5000 + 7;
 
int n, m;
int vis[N], ist[N];
pii e[N];
 
struct Edge { int to, ne; } g[N]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
 
inline bool dfs(int x) {
    vis[x] = 1, ist[x] = 1;
    for fec(i, x, y) {
        if (!vis[y]) { if (!dfs(y)) return 0; }
        else if (ist[y]) return 0;
    }
    ist[x] = 0;
    return 1;
}
 
inline void print1() {
    puts("1");
    for (int i = 1; i <= m; ++i) printf("%d%c", 1, " 
"[i == m]);
    exit(0);
}
 
inline void work() {
    int flag = 1;
    for (int i = 1; i <= n && flag; ++i) if (!vis[i] && !dfs(i)) flag = 0;
    if (flag) print1();
    puts("2");
    for (int i = 1; i <= m; ++i) printf("%d%c", (e[i].fi < e[i].se) + 1, " 
"[i == n]);
}
 
inline void init() {
    read(n), read(m);
    for (int i = 1; i <= m; ++i) {
        int x, y;
        read(x), read(y);
        addedge(x, y);
        e[i].fi = x, e[i].se = y;
    }
}
 
int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

笔者在比赛期间想到一种奇怪的做法, 没有经过严格证明但是可以发现等价于上面的做法。但是由于比赛的时候判断存不存在环没有回溯记录是否在栈中的数组,导致 WA。

思想是按照起点从小到大枚举边,如果把它的颜色计做 (1) 以后,在已经考虑过的边中没有同色环,那么可以为 (1),反之为 (2)

#include<bits/stdc++.h>
 
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
 
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
 
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
 
template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}
 
const int N = 5000 + 7;
 
int n, m, dfc, sccno, tp;
int dfn[N], low[N], scc[N], s[N], vis[N], ans[N], ins[N];
std::vector<pii> v[N];
 
struct Edge { int to, ne, id, ss; } g[N]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
 
inline void dfs(int x) {
    dfn[x] = low[x] = ++dfc;
    s[++tp] = x;
    for fec(i, x, y) {
        if (!dfn[y]) dfs(y), smin(low[x], low[y]);
        else if (!scc[y]) smin(low[x], dfn[y]);
    }
    if (dfn[x] == low[x]) {
        ++sccno;
        while (1) {
            int y = s[tp--];
            scc[y] = sccno; 
//          dbg("scc[%d] = %d
", y, sccno);
            if (x == y) break;
        }
    }
}
inline void tarjan() {
    for (int i = 1; i <= n; ++i) if (!dfn[i]) dfs(i);
}
/*
inline void dfs2(int x, int fr = 0) {
    dbg("x = %d, fr = %d
", x, fr);
    vis[x] = 1;
    for (pii i : v[x]) {
        int y = i.fi, id = i.se;
        ans[id] = fr ^ 1;
        if (!vis[y]) dfs2(y, fr ^ 1);
    }
}*/
 
inline bool dfs2(int x, int col) {
    vis[x] = 1, ins[x] = 1;
    for fec(i, x, y) if (g[i].ss && ans[i] == col) {
        if (!vis[y]) { if (!dfs2(y, col)) return 0; }
        else if (ins[y]) return 0;
    }
    ins[x] = 0;
    return 1;
}
 
inline void work() {
    tarjan();
    int has = 0;
    for (int i = 1; i <= sccno; ++i) {
        int oe, cnt = 0;
        for (int x = 1; x <= n; ++x) if (scc[x] == i) {
            for fec(j, x, y) if (scc[y] == i) v[x].pb(pii(g[j].to, g[j].id));
            oe = x, ++cnt;
        }
        if (cnt == 1) continue;
//      dbg("*** %d
", cnt);
        has = 1;
//      dfs2(oe);
    }
    printf("%d
", has + 1);
//  for (int i = 1; i <= m; ++i) printf("%d%c", ans[i] + 1, " 
"[i == m]);
    for (int x = 1; x <= n; ++x) {
        for fec(i, x, y) {
            memset(vis, 0, sizeof(vis));
            memset(ins, 0, sizeof(ins));
            g[i].ss = 1, ans[i] = 0;
            if (dfs2(y, 0)) ans[i] = 0;
            else ans[i] = 1;
        }
    }
    for (int i = 1; i <= m; ++i) printf("%d%c", ans[i] + 1, " 
"[i == m]);
}
 
inline void init() {
    read(n), read(m);
    for (int i = 1; i <= m; ++i) {
        int x, y;
        read(x), read(y);
        addedge(x, y);
        g[tot].id = i;
    }
}
 
int main() {
    #ifdef hzhkk
//  freopen("hkk.in", "r", stdin);
    #endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

E. Sum Queries?

如果选择三个数,肯定不如选择两个数优。

对于两个第 (i) 位不为 (0) 的数,其和的第 (i)

以上是关于Educational Codeforces Round 72 (Rated for Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27