1. 程式人生 > 實用技巧 >Codeforces Round #665 (Div. 2)

Codeforces Round #665 (Div. 2)

目錄

Codeforces Round #665 (Div. 2)

A. Distance and Axis

題意: 給你一個點a的座標n,求點b的座標,使得∣OB−∣AB∣∣=K∣OB−∣AB∣∣=K
題解: 先判斷n和k的大小關係。b在OA中每移動一個點改變的大小為2,所以判斷n−kn−k的奇偶性即可
程式碼:

#include <bits/stdc++.h>

using namespace std;

int main() {
    int t;
    cin >> t;
    while (t--) {
        int n, k;
        cin >> n >> k;
        if (n > k) {
            if ((n - k) % 2 == 0) cout << 0 << endl;
            else cout << 1 << endl;
        }
        else cout << abs(n - k) << endl;
    }
    return 0;
}

B. Ternary Sequence

題意: 有兩個由0,1,2組成的陣列,分別給你兩個陣列中0,1,2的個數,其中滿足

題解: 要讓2分的儘可能多,然後讓-2分的儘可能少,因此在取完2分的之後,讓0分的儘可能多,這樣2分的就儘可能少了
程式碼:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int main() {
    int T;
    cin >> T;
    while (T--) {
        LL x1, y1, z1, x2, y2, z2;
        cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
        LL res = 0;
        LL t1 = min(z1, y2);
        z1 -= t1;
        y2 -= t1;
        res += t1 * 2;
        LL t2 = min(y1, x2);
        y1 -= t2, x2 -= t2;
        LL t3 = min(y1, y2);
        y1 -= t3, y2 -= t3;
        LL t4 = min(x1, x2);
        x1 -= t4, x2 -= t4;
        LL t5 = min(x1, y2);
        x1 -= t5, y2 -= t5;
        LL t6 = min(x1, z2);
        x1 -= t6, z2 -= t6;
        res -= 2 * min(y1, z2);
        cout << res << endl;
    }
    return 0;
}

C. Mere Array

題意: 給你一個長度為n的陣列a,其中gcd(ai,aj)=min(a) 的兩兩元素可以做交換,求最後能否將陣列a改變成非遞減的陣列
題解: 把a陣列排序後,如果不在最後位置的元素那麼需要進行交換。由於任何兩個數字都可以通過和最小值進行交換,完成這兩個數字的交換。因此,如果不在最後位置的元素不是最小值的整數倍,那麼就無法完成交換。
程式碼:

#include <bits/stdc++.h>

using namespace std;

int const N = 1e5 + 10;
typedef long long LL;
LL a[N], n, T, b[N];
LL INF = 1e18;

int main() {
    // int T;
    cin >> T;
    while (T--) {
        cin >> n;
        LL minv = INF;
        for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]), minv = min(minv, a[i]);
        memcpy(b, a, sizeof a);
        sort(b + 1, b + 1 + n);
        // vector<LL> v;
        int flg = 1;
        for (int i = 1; i <= n; ++i) {
            if (a[i] == b[i]) continue;
            if (a[i] % minv) {
                flg = 0;
                break;
            }
        } 
        if (flg) cout << "YES\n";
        else cout << "NO\n";
        
    }
    return 0;
}

D. Maximum Distributed Tree

題意: 給定一棵n 個結點的樹,對這棵樹分配邊權,使得這棵樹的邊權的乘積為k ,且要求所有兩點的簡單路徑邊權之和最大。k 以質因子的形式給出,有m 個質因子。結果取餘1e9+7
題解: dfs計算出每條邊被經過多少次,經過次數越多的分配的質數越大,即可得到最大值。要注意判斷指數情況和邊數不相等的情況。
程式碼:

#include <bits/stdc++.h>

using namespace std;

int const N = 1e5 + 10;
typedef long long LL;
LL a[N], n, e[N * 2], ne[N * 2], h[N], idx, m, zi[N], fazi[N], T;
LL INF = 1e18;
int mod = 1e9 + 7;
vector<LL> E;

void add(LL a, LL b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

LL dfs(int u, int fa)
{
    LL sum = 1;  // ans記錄子樹的最大值, sum記錄子樹點數和和u點
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == fa) continue;
        
        LL son = dfs(j, u);  
        sum += son;  // 更新sum
    }
    fazi[u] = max((LL)0, n - sum);
    zi[u] = sum;
    return sum;
}

int main() {
    cin >> T;
    while (T--) {
        cin >> n;
        memset(fazi, 0, sizeof fazi);
        E.clear();
        memset(zi, 0, sizeof zi);
        memset(h, -1, sizeof h);
        idx = 0;
        for (int i = 1; i <= n - 1; ++i) {
            LL a, b;
            scanf("%lld %lld", &a, &b);
            add(a, b), add(b, a);
        }
        dfs(1, -1);
        cin >> m;
        vector<LL> v;
        for (int i = 1; i <= m; ++i) {
            LL k;
            scanf("%lld", &k);
            v.push_back(k);
        }
        sort(v.begin(), v.end());
        reverse(v.begin(), v.end());
        for (int i = 2; i <= n; ++i) {
            E.push_back(zi[i] * fazi[i]);
        }
        sort(E.begin(), E.end());
        reverse(E.begin(), E.end());
        // cout << E.size() << endl;
        if (v.size() < E.size()) {
            while (v.size() < E.size()) v.push_back(1);
        }
        else if (v.size() > E.size()) {
            vector<LL> v3(v.begin(), v.begin() + v.size() - E.size() + 1);
            vector<LL> v2(v.begin() + v.size() - E.size() + 1, v.end());
            LL mul = 1;
            for (auto v3i: v3) mul = (mul * v3i ) % mod;
            v2.push_back(mul);
            sort(v2.begin(), v2.end());
            reverse(v2.begin(), v2.end());
            v = v2;
        }
        LL res = 0;
        for (int i = 0; i < E.size(); ++i) {
            res = (res + E[i] * v[i] % mod) % mod;
        }
        cout << res << endl;

    }
    return 0;
}

參考