1. 程式人生 > 實用技巧 >Codeforces Global Round 11

Codeforces Global Round 11

A

只要總和不為零, 肯定成功

總和為正,先放正數

總和為負, 先放負數

int n, m, _, k;
ll a[N], b[N];
 
int main() {
    IOS; //關同步
    for (cin >> _; _; --_) {
        cin >> n; ll m = 0;
        rep (i,1,n) cin >> a[i], m += a[i];
        sort(a + 1, a + 1 + n);
        if (m == 0) cout << "NO\n";
        else {
            cout << "YES\n";
            if (m < 0) rep (i, 1, n) cout << a[i] << ' ';
            else per (i, n, 1) cout << a[i] << ' ';
            cout << '\n';
        }
    } 
    return 0;
}

B

模擬, 先放再在兩段中間的L(先放段數短的)

int n, m, _, k;
char s[N];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m >> s + 1;
        ll ans = 0; VI res;
        int cnt = 0, cc = 0;
        bool g = 1;
        rep (i, 1, n) {
            if (s[i] == 'W' && s[i - 1] == 'W') ans += 2;
            else if (s[i] == 'W') {
                ans += 1, g = 0;
                if (cnt) res.pb(cnt); cnt = 0;
            }
            else if (g) ++cc;
            else ++cnt;
        }
        sort(all(res));
        for (auto i : res) {
            if (m == 0) break;
            if (i > m) { ans += m << 1; m = 0; break; }
            //cout << i << '\n';
            ans += (i << 1) + 1; m -= i;
        }
        if (m && cc) {
            if (m > cc) ans += (!g) + 1 + (cc - 1 << 1), m -= cc;
            else ans += (!g) + 1 + (m - 1 << 1), m = 0;
        }
        if (m && cnt) {
            if (m > cnt) ans += cnt << 1, m -= cnt;
            else ans += m << 1, m = 0;
        }
        cout << ans << '\n';
    } 
    return 0;
}

C

dp, 且時間升序, 也就是大於 2 * r(最長的距離之後, 多走幾個點就可以知道 這一段的最大值)

int n, m, _, k;
int f[N];
 
struct node {
    int x, y, t;
};
 
int main() {
    IOS; cin >> n >> k;
    rep (i, 1, k) f[i] = -inf;
    vector<node> a; a.pb({ 1, 1, 0 });
    rep (i, 1, k) {
        int x, y, t; cin >> t >> x >> y;
        a.pb({ x, y, t });
 
        per (j, i - 1, max(i - (n << 2), 0))
            if (abs(a[j].x - x) + abs(a[j].y - y) <= t - a[j].t) umax(f[i], f[j] + 1);
        umax(m, f[i]);
    }
    cout << m; 
    return 0;
}

D

考慮逆序對, 每次 拼接一段 i 和 i - 1, 是的變為 連著的 i - 1, i

n次操作不正好有序了嗎?

int n, m, _, k;
int a[60], b[60], c[60];
 
int main() {
    IOS; cin >> n;
    rep(i, 1, n) cin >> a[i];
 
    vector<VI> op;
    while (!is_sorted(a + 1, a + 1 + n)) {
        VI cur(1, 0);
        rep(i, 1, n) b[a[i]] = i;
        int i = 1;
        while (b[i] < b[i + 1]) ++i;
        int j = b[i];
        if (b[i + 1] - 1) cur.pb(b[i + 1] - 1);
        while (a[j] - 1 == a[j - 1]) --j;
        cur.pb(j - 1); cur.pb(b[i]);
        if (b[i] != n) cur.push_back(n);
        int cnt = 0;
        per(i, cur.size() - 1, 1)
            rep(j, cur[i - 1] + 1, cur[i]) c[++cnt] = a[j];
        rep(i, 1, n) a[i] = c[i];
        op.pb(cur);
    }
 
    cout << op.size() << '\n';
    for (auto i : op) {
        cout << i.size() - 1;
        rep(j, 1, i.size() - 1) cout << ' ' << i[j] - i[j - 1];
        cout << '\n';
    }
    return 0;
}