• 2018 Benelux Algorithm Programming Contest (BAPC 18)


    2018 Benelux Algorithm Programming Contest (BAPC 18)

    A - A Prize No One Can Win

    int main() {
        IOS; cin >> n >> m; VI a(n); k = 1;
        for (auto &i : a) cin >> i; sort(all(a));
        rep (i, 1, n - 1) if (a[i] + a[i - 1] <= m) ++k;
        cout << k;
        return 0;
    }
    

    B - Birthday Boy

    int c[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    char s[25];
    
    int calc(PII a, PII b) {
        int ans = b.se - 1 - a.se + (a.fi == b.fi ? 0 : c[a.fi]);
        rep(i, a.fi + 1, b.fi - 1) ans += c[i];
        return ans;
    }
    
    int main() {
        scanf("%d", &n); vector<PII> a(n);
        for (auto& i : a) scanf("%s %d-%d", s, &i.fi, &i.se); sort(all(a));
        int x = a[0].fi, y = a[0].se - 1, k = calc(a.back(), { 12, 31 }) + calc({ 1, 1 }, a[0]) + 2;
        if (!y) x = x == 1 ? 12 : x - 1, y = c[x];
        rep(i, 1, n - 1) {
            int cur = calc(a[i - 1], a[i]), cx = a[i].fi, cy = a[i].se - 1;
            if (!cy) cx = cx == 1 ? 12 : cx - 1, cy = c[cx];
            if (cur > k || (cur == k && PII{ x, y } <= PII{ 10, 27 } && PII{ cx, cy } > PII{10, 27}))
                k = cur, x = a[i].fi, y = a[i].se - 1;  
        }
        if (x < 10) cout << 0; cout << x << '-';
        if (y < 10) cout << 0; cout << y;
        return 0;
    }
    

    C - Cardboard Container

    int main() {
        IOS; cin >> n; ans = 2 + n * 4;
        rep (c, 1, n) {
            rep (h, 1, c) {
                if (c * h > n) break;
                if (n % (c * h) == 0) umin(ans, c * h + n / h + n / c << 1);
            }
        }
        cout << ans;
        return 0;
    }
    

    F - Financial Planning

    二分, 注意再循环的时候一旦成功就跳出, 否则会爆ll

    int main() {
        IOS; cin >> n >> m; vector<PLL> a(n);
        for (auto &i : a) cin >> i.fi >> i.se;
        ll l = 1, r = 2e9;
        while (l < r) {
            ll mid = l + r >> 1;
            ll ans = 0;
            for (auto &p : a) {
                ans += max(0ll, p.fi * mid - p.se);
                if (ans >= m) break;
            }
            if (ans >= m) r = mid;
            else l = mid + 1;
        }
        cout << l;
        return 0;
    }
    

    G - Game Night

    最终序列是ABC的全排列, 起点任意, 干脆最终状态为 ABC 或者 ACB

    然后通过滑动窗匹配就行了

    int c[3];
    string s, t[3], a, b;
    
    int work(string& s, string& t, string a) {
        int ans = 0, cnt = 0;
        rep (i, 0, n - 1) cnt += s[i] != t[i]; ans = cnt;
        rep (i, 0, n - 2) {
            if (s[i] == a[0]) ++cnt;
            if (s[i + c[a[0] - 'A']] == a[0]) --cnt;
            if (s[i + c[a[0] - 'A']] == a[1]) ++cnt;
            if (s[i + c[a[0] - 'A'] + c[a[1] - 'A']] == a[1]) --cnt;
            if (s[i + c[a[0] - 'A'] + c[a[1] - 'A']] == a[2]) ++cnt;
            if (s[i + c[a[0] - 'A'] + c[a[1] - 'A'] + c[a[2] - 'A']] == a[2]) --cnt;
            umin(ans, cnt);
        }
        return ans;
    }
    
    int main(){
        IOS; cin >> n >> s;
        for (auto i : s) ++c[i - 'A']; s += s;
        rep (i, 0, 2) string(c[i], 'A' + i).swap(t[i]);
        a = t[0] + t[1] + t[2], b = t[0] + t[2] + t[1];
        cout << min(work(s, a, "ABC"), work(s, b, "ACB"));
        return 0;
    }
    

    I - In Case of an Invasion, Please...

    最小化值, 想二分, 找到可用边, 然后网络流

    但复杂度必炸, 注意到最多10个避难点

    最多有 1 << 10 种状态, 复杂度就够了

    把能到达完全相同数量和编号的点合并, 最多有1024种,

    s 向 这1024状态连边, 1024在向 避难点 连边, 避难点在向 t 连边

    相当与我们实在二分这1024种状态到避难点的最小最大长度, 那最多有 1024 * 10条边

    排序二分边的序号即可

    const int N = 1e5 + 15, M = 2e4 + 5;
    const ll inf = 1ll << 60;
    
    int n, m, _, k;
    int a[N];
    ll dis[11][N], sum;
    bool v[N];
    PII sh[11];
    vector<PII> e[N];
    
    void dij(int s, ll* d) {
        memset(v, 0, sizeof v);
        priority_queue<pair<ll, int>> q; q.push({d[s] = 0, s});
        while (!q.empty()) {
            int x = q.top().se; q.pop();
            if (v[x]) continue; v[x] = 1;
            for (auto &y : e[x]) if (d[y.fi] > d[x] + y.se)
                q.push({-(d[y.fi] = d[x] + y.se), y.fi});
        }
    }
    
    int h[1050], ne[M], to[M], tot, now[1050];
    int d[1050], s = 1025, t = 1026;
    ll co[M], st[1050];
    
    void add(int u, int v, ll c) {
        ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
        ne[++tot] = h[v]; to[h[v] = tot] = u; co[tot] = 0;
    }
    
    bool bfs() {
        memset(d, 0, sizeof d); memcpy(now, h, sizeof h);
        queue<int> q; q.push(s); d[s] = 1;
        while (!q.empty()) {
            int x = q.front(); q.pop();
            for (int i = h[x]; i; i = ne[i]) if (co[i]) {
                int y = to[i];
                if (d[y]) continue;
                d[y] = d[x] + 1; q.push(y);
                if (y == t) return 1;
            }
        }
        return 0;
    }
    
    ll dinic(int x, ll flow) {
        if (x == t) return flow;
        ll rest = flow, k;
        for (int& i = now[x]; i && rest; i = ne[i]) if (co[i]) {
            int y = to[i];
            if (d[y] != d[x] + 1) continue;
            k = dinic(y, min(rest, co[i]));
            if (!k) { d[y] = 0; continue; }
            co[i] -= k, co[i ^ 1] += k; rest -= k;
        }
        return flow - rest;
    }
    
    bool check(ll mid) {
        memset(h, 0, sizeof h); memset(st, 0, sizeof st); tot = 1;
        rep (i, 1, n) {
            int cur = 0;
            rep (j, 1, k) if (dis[j][i] <= mid) cur ^= 1 << j - 1;
            st[cur] += a[i];
        }
        rep (i, 0, (1 << k) - 1) if (st[i]) {
            rep (j, 1, k) if (i >> j - 1 & 1) add(i, j + t, inf);
            add(s, i, st[i]);
        }
        rep (i, 1, k) add(i + t, t, sh[i].se);
        ll flow = 0, mx = 0;
        while (bfs()) while(flow = dinic(s, inf)) mx += flow;
        return mx == sum;
    }
    
    int main() {
        read(n, m, k); vector<ll> c;
        memset(dis, 0x3f, sizeof dis);
        rep (i, 1, n) read(a[i]), sum += a[i];
        rep (i, 1, m) {
            int u, v, c; read(u, v, c);
            e[u].pb({v, c}); e[v].pb({u, c});
        }
        rep (i, 1, k) {
            read(sh[i].fi, sh[i].se); dij(sh[i].fi, dis[i]);
            rep (j, 1, n) c.emplace_back(dis[i][j]);
        }
        sort(all(c));
        int l = 1, r = unique(all(c)) - c.begin(), ans;
        while (l <= r) {
            ll mid = l + r >> 1;
            if (check(c[mid - 1])) r = mid - 1, ans = mid;
            else l = mid + 1;
        }
        write(c[ans - 1]);
        return 0;
    }
    

    J - Janitor Troubles

    多边形面积公式

    int main() {
        IOS; double a, b, c, d; cin >> a >> b >> c >> d;
        double p = (a + b + c + d) / 2;
        cout << setprecision(7) << sqrt((p - a) * (p - b) * (p - c) * (p - d));
        return 0;
    }
    

    K - Kingpin Escape

    不存在割边加点

    int deg[N];
    VI h[N], a;
    
    void dfs(int x, int f) {
        if (deg[x] == 1) a.pb(x);
        for (auto y : h[x]) if (y != f) dfs(y, x);
    }
    
    int main(){
        IOS; cin >> n >> m; ++m;
        rep (i, 2, n) {
            int u, v; cin >> u >> v; ++v, ++u;
            h[u].pb(v); h[v].pb(u); ++deg[v]; ++deg[u];
        }
        dfs(m, 0);
        cout << (a.size() + 1 >> 1) << '
    ';
        rep (i, 1, a.size() >> 1) cout << a[i - 1] - 1 << ' ' << a[i + a.size() / 2 - 1] - 1 << '
    ';
        if (a.size() & 1) cout << a[a.size() >> 1] - 1 << ' ' << a.back() - 1;
        return 0;
    }
    
  • 相关阅读:
    网站安全策略
    防止表单重复提交的几种策略
    Laravel5中防止XSS跨站攻击的方法
    PHP + ORACLE 远程连接数据库环境配置
    iview table表格内容为数组或者对象的子元素时问题讨论
    jquery中 $(xxx).each() 和 $.each()的区别,以及enter键一键登录
    vue.js 强行赋值、刷新数组或者对象 方法之 $.set()
    vue 组件,以及组件的复用
    vue 和 jquery混合使用
    JS清除空格之trim()方法
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14289920.html
Copyright © 2020-2023  润新知