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;
}
posted @ 2020-10-11 17:00  洛绫璃  阅读(167)  评论(0编辑  收藏  举报