zoukankan      html  css  js  c++  java
  • 2020ICPC·小米 网络选拔赛第一场

    A

    枚举倍数就行了

    然后挨个去查找, 调和级数nlogn,

    这就是好多人这样过的, 这是数据水了....

    毕竟 n 是 1e7, 这是卡爆他们的数据

    100000
    1, 2, ..., 9999, 10000000 
    

    大概需要计算1e8+(还不算循环里的两条指令), 再好的评侧鸡也不能跑到 1e8+ 吧..

    所以我们应注意到, 在累加 i 的时候会重复, 枚举素数倍就好了, 复杂度就成了 nloglogn, 2e7+

    const int N = 1e7 + 5;
     
    int n, m, _, k;
    ll a[N], b[N], d[N];
    int prime[N], tot;
    bool v[N];
    
    void init(int n) {
        rep (i, 2, n) {
            if (!v[i]) prime[++tot] = i;
            for (int j = 1; prime[j] <= n / i && j <= tot; ++j) {
                v[prime[j] * i] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    
    int main() {
        IOS; cin >> n; init(1e7);
        rep (i, 1, n) cin >> a[i], ++b[a[i]];
        ll ans = 0;
        per (i, 1e7, 1) {
            for (int j = 1; prime[j] <= 1e7 / i; ++j) umax(d[i], d[prime[j] * i]);
            umax(ans, d[i] += b[i]);
        }
        cout << ans;
        return 0;
    }
    

    B

    对每个点能到的点(即 x 到 y 的直线路径上没 墙 )建边, 跑最短路

    怎么判线段相交就不贴了, 板子太长, 用你自己的几何板子就行了

    int n, m, k, _;
    int h[N], ne[M << 1], to[M << 1], tot;
    double co[M << 1], dis[N];
    bool v[N];
    
    void add(int u, int v, double c) {
        ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
        ne[++tot] = h[v]; to[h[v] = tot] = u; co[tot] = c; 
    }
    
    int main() {
        IOS; cin >> n >> m >> k;
        rep (i, 0, k) pos[i << 1].in(), pos[i << 1 | 1].in();
        rep (i, 0, (k << 1) + 1) {
            dis[i] = 2e9;
            rep (j, i + 1, (k << 1) + 1) {
                bool f = 1;
                rep (_, 0, k - 1) 
                    if (pan_cross_LL(pos[i], pos[j], pos[_ << 1], pos[_ << 1 | 1])) f = 0;
                if (f) add(i, j, Len(pos[i] - pos[j]));
            }
        }
        priority_queue<pair<double, int>> q; q.push({ 0, k << 1}); dis[k << 1] = 0;
        while (!q.empty()) {
            int x = q.top().se; q.pop();
            if (v[x]) continue; v[x] = 1;
            for (int i = h[x]; i; i = ne[i]) {
                int y = to[i]; double w = dis[x] + co[i];
                if (w >= dis[y]) continue;
                dis[y] = w; q.push({ -w, y });
            }
        }
        cout << setiosflags(ios::fixed) << setprecision(4) << dis[k << 1 | 1];
        return 0;
    }
    

    C

    题意模拟,签到题

    int main() {
        IOS; string s;
        cin >> s; ll cnt = 0;
        rep (i, 0, s.size() - 1) {
            if (s[i] == 'w') ++cnt;
            if (!i || s[i] == 'v') continue;
            if (s[i] != 'w') continue;
            if (s[i - 1] == 'w') ++cnt;
        }
        cout << cnt;
        return 0;
    }
    

    D

    tarjan板子题, 板子就不贴, 其他专栏贴过

    int main() {
        IOS; cin >> n >> m;
        tot = 1; totc = df = 0;
        rep(i, 1, n) h[i] = dfn[i] = cut[i] = 0;
        rep(i, 1, m) {
            int u, v; cin >> u >> v;
            add(u, v); add(v, u);
        }
    
        int sum = 0;
        rep(i, 1, n) if (!dfn[i]) root = i, tarjan(i), ++sum;
    
        rep(i, 1, n) cout << sum + cut[i] << ' ';
        return 0;
    }
    

    F

    二分就行, 记得 m * L 的地方可能爆ll, 用__int128

    ll r[N], l[N], L, R, a[N];
     
    bool check(__int128 m) {
        ll cur = 0, res = 0;
        rep(i, 1, n) {
            ll c = a[i] / m;
            if (c < l[i]) return 0;
            umin(c, r[i]); cur += c * m;
            if (c == r[i]) continue;
            res += a[i] % m;
        }
        if (cur + res >= m * L) return 1;
        return 0;
    }
     
    int main() {
        IOS; cin >> n >> L >> R;
        ll mx = 0, mi = 0, s = 0;
        rep(i, 1, n) cin >> a[i], s += a[i];
        rep(i, 1, n)
            cin >> l[i] >> r[i], mi += l[i], mx += r[i];
        if (mi > R || mx < L) { cout << 0; return 0; }
        ll l = 0, r = s;
        while (l < r) {
            ll mid = l + r + 1 >> 1;
            if (check(mid)) l = mid;
            else r = mid - 1;
        }
        cout << l;
        return 0;
    }
    

    I

    搜索low爆了

    你在每个点走的方向唯一的, 那直接将 这个点和将要走到的点合并不好吗?

    对环打标记

    最后父亲等于自己的 且没有标记的, 是能走出去的点, 答案就是这些点和这些点的孩子的个数

    int get(int x, int y) {
        return (x - 1) * m + y;
    }
     
    int main() {
        IOS; cin >> n >> m;
        rep(i, 1, n) rep(j, 1, m) k = get(i, j), f[k] = k, siz[k] = 1;
        rep(i, 1, n) {
            cin >> s[i] + 1;
            rep(j, 1, m)
                if (s[i][j] == 'S') { if (i + 1 <= n) unit(get(i + 1, j), get(i, j)); }
                else if (s[i][j] == 'W') { if (i - 1 > 0) unit(get(i - 1, j), get(i, j)); }
                else if (s[i][j] == 'A') { if (j - 1 > 0) unit(get(i, j - 1), get(i, j)); }
                else { if (j + 1 <= m) unit(get(i, j + 1), get(i, j)); }
        }
        int ans = 0;
        rep(i, 1, n) rep(j, 1, m) {
            int id = get(i, j);
            if (f[id] != id || v[id]) continue;
            ans += siz[id];
        }
        cout << ans;
        return 0;
    }
    

    J

    和开关问题一样, 还比他简单, 直接从 (1, 1) 开始改, 当无法改的的时候 不为0 就 QAQ

    主要是裸一个二维区间查询和修改的数据结构, 线段树和树状数组都行, 我用的树状(代码短)

    
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> m >> x >> y;
            rep(i, 1, n) rep(j, 1, m) {
                cin >> a[i][j];
                c[0][i][j] = c[1][i][j] = c[2][i][j] = c[3][i][j] = 0; //树状数组的初始化
            }
            bool f = 1;
            rep(i, 1, n - x + 1) {
                if (!f) break;
                rep(j, 1, m - y + 1) {
                    int cur = a[i][j] + ask(i, j, i, j);
                    if (cur < 0) { f = 0; break; }
                    if (cur == 0) continue;
                    add(i, j, i + x - 1, j + y - 1, -cur);
                }
                rep(j, m - y + 2, m) {
                    int cur = a[i][j] + ask(i, j, i, j);
                    if (cur != 0) { f = 0; break; }
                }
            }
            rep(i, n - x + 2, n) {
                if (!f) break;
                rep(j, 1, m) {
                    int cur = a[i][j] + ask(i, j, i, j);
                    if (cur != 0) { f = 0; break; }
                }
            }
            if (f) cout << "^_^
    ";
            else cout << "QAQ
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    django--orm操作
    路由
    django ----视图和路由
    DJango 前三天小结
    JQuery----操作01
    前端---JQuery初识
    前端----jsDOM
    前端---js02
    前端-----js
    面向对象
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13879662.html
Copyright © 2011-2022 走看看