Codeforces Round #592 (Div. 2)


C題全員fst,不過幸好過了D、E,上了62分。現在Rating:1815,上紫指日可待。

先貼個代碼,心情好的時候回來補題解QwQ。

Codeforces1244A. Pens and Pencils(水題)

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } int main() { int t; cin >> t; while (t--){ int a, b, c, d, k; read(a, b, c, d, k); int ans1 = a/c + (a%c>0); int ans2 = b/d + (b%d>0); if (ans1 + ans2 <= k) { cout << ans1 << ' ' << ans2 << endl; } else { cout << -1 << endl; } } return 0; }
View Code

 

Codeforces1244B. Rooms and Staircases(兩種情況枚舉一下,水題)

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } int main() { int t; cin >> t; while (t--) { int n; read(n); string s; cin >> s; int ans = n; int pre = -1; for (int i = 0; i < n; i++) { if (s[i] == '1') { pre = i; break; } } if (pre != -1) { ans = max(ans, 2*(n - pre)); } pre = -1; for (int i = n-1; i >= 0; i--) { if (s[i] == '1') { pre = i; break; } } if (pre != -1) { ans = max(ans, 2*(pre+1)); } cout << ans << endl; } return 0; }
View Code

 

Codeforces1244C. The Football Season(暴力,可以證明循環節長度不超過max(w,d),全民fst)

UPD:

很多人WA on test 62,是因為算出了負數的答案。TLE on test 66的話可能是忘記break了。

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } int main() { ll n, p, w, d; read(n, p, w, d); ll cntw = 0, cntd = 0, cntl = 0; if (d < w) { ll sum = 0; for (; cntd <= w; cntd++) { if ((p-sum) % w == 0) { break; } sum += d; } cntw = (p-sum) / w; cntl = n-cntw-cntd; if ((p-sum)%w != 0 || cntw+cntd > n) { puts("-1"); } else { if (cntw < 0 || cntd < 0 || cntl < 0) { return 0 * puts("-1"); } printf("%I64d %I64d %I64d\n", cntw, cntd, cntl); } } else if (d >= w) { ll sum = 0; for (; cntw <= d; cntw++) { if ((p-sum) % d == 0) { break; } sum += w; } cntw = (p-sum) / d; cntl = n-cntw-cntd; if ((p-sum)%d != 0 || cntw+cntd > n) { puts("-1"); } else { if (cntw < 0 || cntd < 0 || cntl < 0) { return 0 * puts("-1"); } printf("%I64d %I64d %I64d\n", cntw, cntd, cntl); } } return 0; }
View Code

 

Codeforces1244D. Paint the Tree

UPD:

可以發現給出的樹不是鏈的情況都是不可能染色的。對於鏈的情況,枚舉前三個節點的顏色,暴力跑一邊取最小值就好了。

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } /** graph **/
int tot = 0; int head[N], nxt[M<<1], ver[M<<1]; int deg[N]; void addEdge(int u, int v) { nxt[++tot] = head[u], ver[tot] = v, head[u] = tot; deg[u]++; } int n; ll c[N][4]; void input() { read(n); memset(head, -1, sizeof head); for (int i = 1; i <= 3; i++) { for (int j = 1; j <= n; j++) { read(c[j][i]); } } for (int i = 1; i <= n-1; i++) { int u, v; read(u, v); addEdge(u, v); addEdge(v, u); } } bool vis[N]; vector <int> nodes; void dfs(int u) { vis[u] = true; nodes.push_back(u); for (int i = head[u]; i != -1; i = nxt[i]) { int v = ver[i]; if (vis[v]) continue; dfs(v); } } ll f[N][4][4];//i-th node choose j-th color's and previous node is k-th color tot cost
int pre[N][4][4]; int ans[N]; ll dp() { ll res = 1e18; vector <int> vs; for (int i = 1; i <= 3; i++) vs.push_back(i); do { ll tmpres = 0; for (int i = 0; i < sz(nodes); i++) { int u = nodes[i]; tmpres += c[u][vs[i%3]]; } if (res > tmpres) { res = tmpres; for (int i = 0; i < sz(nodes); i++) { int u = nodes[i]; ans[u] = vs[i%3]; } } }while (next_permutation(vs.begin(), vs.end())); return res; } int main() { input(); bool ok = true; int st = 1; for (int i = 1; i <= n; i++) { if (deg[i] == 1) { st = i; } if (deg[i] >= 3) { ok = false; break; } } if (!ok) { puts("-1"); } else { memset(vis, false, sizeof vis); dfs(st); ll res = dp(); cout << res << endl; for (int i = 1; i <= n; i++) { printf("%d%c", ans[i], i == n ? '\n' : ' '); } } return 0; }
View Code

 

Codeforces1244E. Minimizing Difference(一個很經典的模擬題)

UPD:

我的做法是把所有數值的數量統計好,並把所有數值放在一個vector里面排序去重。

用l和r指針分別指向最小的數和最大的數。

每次考慮移動數量比較小的一邊,並考慮是否能向l+1(或r-1)合並。能合並的話,就把兩個數量加起來,並最小值變成l+1(或最大值變成r-1);不能合並說明k要用完了,看最多能改變多少最小值(或最大值),修改之后就直接出答案了。

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 100005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } ll a[N]; unordered_map <ll, ll> mcnt; vector <ll> v; int main() { int n; ll k; read(n, k); for (int i = 1; i <= n; i++) { read(a[i]); v.push_back(a[i]); mcnt[a[i]]++; } sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); int pl = 0, pr = sz(v)-1; ll vall = v[pl], valr = v[pr]; ll cntl = mcnt[vall], cntr = mcnt[valr]; ll _min = vall, _max = valr; while (pl < pr && k > 0) { vall = v[pl], valr = v[pr]; if (cntl < cntr) { // pl+
            ll vallr = v[pl+1]; ll cutk = (vallr - vall) * cntl; if (k >= cutk) { k -= cutk; pl++; cntl += mcnt[vallr]; _min = vallr; } else { ll add = k / cntl; k = 0; _min += add; } } else if (cntl >= cntr) { ll valrl = v[pr-1]; ll cutk = (valr - valrl) * cntr; if (k >= cutk) { k -= cutk; pr--; cntr += mcnt[valrl]; _max = valrl; } else { ll add = k / cntr; k = 0; _max -= add; } } } ll ans = _max - _min; cout << ans << endl; return 0; }
View Code

 

Codeforces1244F. Chips(模擬)

UPD:

補完這題發現這場真的是手速場,一堆模擬題。錯失上分的大好機會QAQ。

用手模擬一下樣例,就可以發現兩個結論:

1、連續的W或者B不論執行多少次操作,都不會改變。

2、連續的形如WBWB的子串,每次操作會翻轉一次。

形如WWBWBWW,中間的BWB在執行一次操作之后就會翻轉成WBW,兩側的WBW會合並到兩側的W中。

此時我們就可以模擬了。將所有形如WBWB的子串的兩端(l,r)記錄下來,每次操作將兩段的點修改為和相鄰的連續的W或者B相同,再l++,r--就好了。

特別地,如果沒有連續的W或者B,每次操作都會使整個字符串翻轉,如果翻轉偶數次,則不變,奇數次每個W改成B,B改成W輸出就好了。

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 200005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define upperdiv(a,b) (a/b + (a%b>0))
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)

using namespace std;
typedef long long ll;
typedef double db;

/** fast read **/
template <typename T>
inline void read(T &x) {
    x = 0; T fg = 1; char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-') fg = -1;
        ch = getchar();
    }
    while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
    x = fg * x;
}
template <typename T, typename... Args>
inline void read(T &x, Args &... args) { read(x), read(args...); }

int n, k;
bool vis[N];
int posl[N], posr[N];
string s;
void input() {
    read(n, k);
    cin >> s;
    for (int i = 0; i < n; i++) {
        if (i == 0) posl[i] = n-1;
        else posl[i] = i-1;

        if (i == n-1) posr[i] = 0;
        else posr[i] = i+1;

        vis[i] = false;
    }
}
struct SNode{
    int p;
    int type; // l1, r2;
    bool operator < (const SNode& x) const {
        return p < x.p;
    }
};
int main()
{
    input();
    queue <SNode> ps, tmpps;
    for (int l = 0; l < n; l++) {
        int r = l;
        while (r+1 < n && s[r+1] == s[r]) {
            ++r;
        }
        if (r-l+1 >= 2) {
            for (int i = l; i <= r; i++)
                vis[i] = true;
            ps.push(SNode{l, 1});
            ps.push(SNode{r, 2});
            l = r;
        }
    }
    if (!vis[0] && !vis[n-1] && s[0] == s[n-1]) {
        ps.push(SNode{n-1, 1});
        ps.push(SNode{0, 2});
        vis[0] = vis[n-1] = true;
    }

    /** 000000pr0000pl000 **/
    bool can_reverse = false;
    for (int i = 1; i <= k; i++, can_reverse = !can_reverse) {
        if (ps.empty())
            break;
        while (!ps.empty()) {
            SNode tmpr = ps.front(); ps.pop();
            if (tmpr.type == 1) {
                ps.push(tmpr);
                continue;
            }
            SNode tmpl = ps.front(); ps.pop();
            int pl = tmpl.p, pr = tmpr.p;
            if (posl[pl] != pr && posl[posl[pl]] != pr) {
                int prr = posr[pr], pll = posl[pl];
                s[prr] = s[pr]; vis[prr] = true; tmpps.push(SNode{prr, 2});
                s[pll] = s[pl]; vis[pll] = true; tmpps.push(SNode{pll, 1});
            }
            else if (posl[posl[pl]] == pr) {
                int p = posl[pl]; vis[p] = true;
                if (s[pl] == s[pr])
                    s[p] = s[pl];
                else if (can_reverse) {
                    if (s[p] == 'B') s[p] = 'W';
                    else if (s[p] == 'W') s[p] = 'B';
                }
            }
        }

        while (!tmpps.empty()) {
            ps.push(tmpps.front()); tmpps.pop();
        }
    }
    if (can_reverse) {
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                if (s[i] == 'B') s[i] = 'W';
                else if (s[i] == 'W') s[i] = 'B';
            }
        }
    }
    cout << s << endl;

    return 0;
}
/*
6 1
BWBBWW

*/
View Code

 

Codeforces1244G. Running in Pairs(構造,大水題!!!!)

UPD:

顯然最小的和是$sum_{i=1}^{n}i$= n*(n+1)/2。如果k小於這個最小值,那顯然是不行的。

否則必定是可行的。不妨先將p和q都設1,2,……,n。sum = n*(n+1)/2。

從n到1枚舉i,考慮是否能把q中的元素i放到q中第一個沒被修改的點,從而讓sum接近但不超過k。如果超過k就跳過當前的i。最多能接近$sum_{i=1}^{n/2}(n-i+1)-i$,這樣的操作最后會把步長收斂到1,所以是最優的。

#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 1000005
#define M 100005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define mp(a,b) make_pair(a, b)
#define endl '\n'
#define lowbit(x) (x&-x)
 
using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } int ans1[N], ans2[N]; int main() { ll n, k; read(n, k); ll minres = n*(n+1) / 2; ll maxres = 0; for (int i = 1; i <= n; i++) { ans1[i] = i; ans2[i] = n-i+1; maxres += max(ans1[i], ans2[i]); } if (k < minres) return 0 * puts("-1"); else if (k >= maxres) { k = maxres; } else { int l = 1, r = n; ll sum = minres; for (int i = 1; i <= n; i++) { if (r >= ans1[i] && sum + r - ans1[i] <= k) { sum += r - ans1[i]; ans2[i] = r--; } else { ans2[i] = l++; } } } cout << k << endl; for (int i = 1; i <= n; i++) printf("%d%c", ans1[i], " \n"[i==n]); for (int i = 1; i <= n; i++) printf("%d%c", ans2[i], " \n"[i==n]); return 0; } /* 5 20 */
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM