• 牛客挑战赛47


    牛客挑战赛47

    A 一道GCD问题

    加个相同的数, gcd最大, 相当于所有数 % maxgcd 的余数相同

    每个数相互减一下, 余数就被减没了

    int main() {
        IOS; cin >> n;
        rep (i, 1, n) cin >> a[i]; sort(a + 1, a + 1 + n);
        a[n] -= a[n - 1];
        per (i, n - 1, 2) a[i] -= a[i - 1], a[n] = __gcd(a[n], a[i]);
        cout << a[n] << ' ' << (a[n] - a[1] % a[n]) % a[n];
        return 0;
    }
    

    B 又一道 GCD 问题

    记录每个因子出现的次数就好了

    int c[N], b[N], ans[N];
    
    int main() {
        IOS; cin >> n;
        rep (i, 1, n) {
            cin >> m;
            rep (j, 1, m / j) if (m % j == 0)
                if (j == m / j) ++c[j];
                else ++c[j], ++c[m / j];
        }
        rep (i, 1, 1e5) b[c[i]] = i;
        per (i, n, 2) ans[i] = max(ans[i + 1], b[i]);
        rep (i, 2, n) cout << ans[i] << ' ';
        return 0;
    }
    

    C 条件

    本来想用弗洛伊德做的结果 (O(n^3)) 妥妥超时

    那就改成每个点跑一边迪杰斯特拉 (O(n^2logn)) 复杂度还行

    VI e[2][N];
    int d[2][N][N], g[N][N];
    bool v[2][N][N];
    
    void dij(int s, int* d, bool* v, VI* e) {
        rep(i, 1, n) d[i] = 1e9; d[s] = 0;
        priority_queue<PII> q; q.push({ 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] > d[x] + 1) 
                    q.push({ -(d[y] = d[x] + 1), y });
        }
    }
    
    int main() {
        IOS; cin >> n >> m1 >> m2 >> k;
        rep(i, 1, m1) {
            int x, y; cin >> x >> y;
            e[0][x].pb(y);
        }
        rep(i, 1, n) dij(i, d[0][i], v[0][i], e[0]), g[i][i] = 1;
        rep(i, 1, m2) {
            int x, y; cin >> x >> y;
            g[x][y] = 1;
        }
        rep(i, 1, n) rep(j, 1, n) if (!g[i][j]) e[1][i].pb(j);
        rep(i, 1, n) dij(i, d[1][i], v[1][i], e[1]);
        rep(i, 1, k) {
            int x, y; cin >> x >> y;
            cout << (d[0][x][y] < 1e9 ? "Yes " : "No ") << (d[1][x][y] < 1e9 ? "Yes
    " : "No
    ");
        }
        return 0;
    }
    

    我的天, 评测姬nb, 弗洛伊德过了, 数据估计是随机的, 快了700ms+, 慢了t了

    int main() {
        read(n, m1, m2, k);
        rep (i, 1, n) d[i][i] = 1;
        rep (i, 1, m1) { read(x, y); d[x][y] = 1; }
        rep (i, 1, m2) { read(x, y); d[x][y] = -1; }
        rep (k, 1, n) rep (i, 1, n) rep (j, 1, n) umax(d[i][j], min(d[i][k], d[k][j]));
        rep (i, 1, k) {
            read(x, y);
            switch (read(x, y), d[x][y]) {
                case 1 : puts("Yes Yes"); break;
                case 0 : puts("No Yes"); break;
                case -1 : puts("No No");
            }
        }
        return 0;
    }
    

    ⭐D Lots of Edges

    把点变成权值, 跑迪杰斯特拉就行, 边权都是 0, 1, 直接双端队列就行, 挺好的一道题

    int d[N], a[N], c = (1 << 17) - 1;
    bool v[N], b[N];
    
    void dij(int s) {
        memset(d, 0x3f, sizeof d); d[c ^ s] = v[s] = 1;
        deque<int> q; q.push_back(c ^ s);
        while (!q.empty()) {
            int x = q.front(); q.pop_front();
            if (v[x]) continue; v[x] = 1;
            rep (i, 0, 16) if (x >> i & 1) if (d[x ^ (1 << i)] > d[x])
                d[x ^ (1 << i)] = d[x], q.push_front(x ^ (1 << i));
            if (b[x] && d[c ^ x] > d[x] + 1) d[c ^ x] = d[x] + 1, q.push_back(c ^ x);
        }
    }
    
    int main() {
        IOS; cin >> n >> m;
        rep (i, 1, n) cin >> a[i], b[a[i]] = 1; dij(a[m]);
        rep (i, 1, n) cout << (i == m ? 0 : d[a[i]] == d[N - 1] ? -1 : d[a[i]]) << ' ';
        return 0;
    }
    
  • 相关阅读:
    excel转换为dta格式
    移动pdf
    豆瓣爬虫
    python给证件照换底色
    OS模块
    决策树参数
    Pandas数据连接
    Sklearn用法
    numpy.loadtxt()用法
    单片机基础(五):定时/计数器的工作原理及工作方式
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14257645.html
Copyright © 2020-2023  润新知