Educational Codeforces Round 34

Educational Codeforces Round 34 

A. Hungry Student Problem

枚举一个就完事了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;

void solve(){
    int x;
    sci(x);
    for(int a = 0; a <= x / 3; a++){
        int l = x - a * 3;
        if(l%7==0){
            cout << "YES" << endl;
            return;
        }
    }
    cout << "NO" << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    int n; sci(n);
    while(n--) solve();
    return 0;
}

B. The Modcrab

二分用药次数,必然先嗑完药再打

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;

void solve(){
    int h1, a1, c1, h2, a2;
    sci(h1); sci(a1); sci(c1); sci(h2); sci(a2);
    auto check = [&](int m){
        int h = h1 + (c1 - a2) * m;
        int s1 = h2 / a1 + (h2 % a1 != 0 ? 1 : 0);
        int s2 = h / a2 + (h % a2 != 0 ? 1 : 0);
        return s1 <= s2;
    };
    int l = 0, r = 1e5+7;
    while(l<=r){
        int mid = (l + r) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    int cnt = h2 / a1 + (h2 % a1 != 0 ? 1 : 0);
    cout << cnt + l << endl;
    for(int i = 1; i <= l; i++) cout << "HEAL" << endl;
    for(int i = 1; i <= cnt; i++) cout << "STRIKE" << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

C. Boxes Packing

排个序然后用个优先队列维护每个单调序列的最大值,每次选最小的然后把当前值作为单调序列的最大值

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;

void solve(){
    int n; sci(n);
    vi A(n); for(int &x : A) sci(x);
    sort(all(A));
    priority_queue<int, vi, greater<int> > que;
    for(int x : A){
        if(que.empty() or que.top()>=x) que.push(0);
        auto p = que.top();
        que.pop();
        que.push(x);
    }
    cout << que.size() << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

D. Almost Difference

先算所有的(y-x)的和,然后把差值为(1)的单独算一下

会爆(long long),用了(\_\_int\_128t)

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;


void print(__int128 x){
    if(x < 0){
        x = -x;
        putchar('-');
    }
    if(x > 9) print(x/10);
    putchar(x%10 + '0');
}
void solve(){
    int n; sci(n);
    vi A(n); for(int &x : A) sci(x);
    __int128_t ret = 0;
    for(LL i = 0, s = 0; i < n; s += A[i], i++) ret += i * A[i] - s;
    int p1 = 0, n1 = 0;
    map<int,int> msk;
    for(int i = 0; i < n; i++){
        p1 += msk[A[i]-1];
        n1 += msk[A[i]+1];
        msk[A[i]]++;
    }
    ret -= p1; ret += n1;
    print(ret);
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

E. Swapping Characters

如果全部都一样,就随便换两个位置就好了

否则找两个不一样的,找到这些不一样的位置,分别枚举两个串的不同位置和其他位置交换得到的串,和所有串匹配一下判断是否符合条件即可

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 5e3+7;
int k, n;
string s[MAXN];
void solve(){
    ____();
    cin >> k >> n;
    for(int i = 0; i < k; i++) cin >> s[i];
    sort(s,s+k);
    k = unique(s,s+k) - s;
    auto check = [&](string &str, int id){
        bool same = false;
        set<char> S;
        for(char c : str){
            if(S.count(c)){
                same = true;
                break;
            }
            S.insert(c);
        }
        vi A(26);
        for(char x : str) A[x-'a']++;
        for(int i = 0; i < k; i++){
            if(i==id) continue;
            int dif = 0;
            for(int j = 0; j < n; j++) if(s[id][j]!=s[i][j]) dif++;
            vi B(26);
            for(char x : s[i])  B[x-'a']++;
            for(int j = 0; j < 26; j++) if(A[j]!=B[j]) return false;
            if(dif==2 or (dif==0 and same)) continue;
            return false;
        }
        return true;
    };
    for(int i = 0; i < k; i++) for(int j = i + 1; j < k; j++){
        if(s[i]==s[j]) continue;
        vi pos;
        for(int x = 0; x < n; x++) if(s[i][x]!=s[j][x]) pos << x;
        if(pos.size()==1 or pos.size()>4){
            cout << -1 << endl;
            return;
        }
        for(int p1 : pos){
            for(int x = 0; x < n; x++){
                if(x==p1) continue;
                bool ok = true;
                swap(s[i][p1],s[i][x]);
                if(check(s[i],i)){
                    cout << s[i] << endl;
                    return;
                }
                swap(s[i][p1],s[i][x]);
            }
        }
        for(int p1 : pos){
            for(int x = 0; x < n; x++){
                if(x==p1) continue;
                bool ok = true;
                swap(s[j][p1],s[j][x]);
                if(check(s[j],j)){
                    cout << s[j] << endl;
                    return;
                }
                swap(s[j][p1],s[j][x]);
            }
        }
    }
    if(k==1) swap(s[0][0],s[0][1]), cout << s[0] << endl;
    else cout << -1 << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

F. Clear The Matrix

最大的正方形只有(4),考虑(DP),对于每一列,其实只和它前面的三列有关系,那么可以用(12)位二进制来存前三列的状态,(dp[i][msk])表示第(i)列之前已经完全清除且从第(i)列开始的三列的状态是(msk)的最小花费,通过枚举四种正方形和填在最左边列的位置进行转移

为了方便可以多加四行

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 1e3+7;
int n, c[4], sta[MAXN], clr[4];
char s[4][MAXN];
int clear(int msk, int sz, int pos){ return msk & (((1 << 12) - 1) ^ (clr[sz-1] << pos)); }
void solve(){
    clr[0] = 1 << 8;
    clr[1] = (3 << 4) | (3 << 8);
    clr[2] = 7 | (7 << 4) | (7 << 8);
    sci(n);
    for(int i = 0; i < 4; i++) sci(c[i]);
    for(int i = 0; i < 4; i++) scs(s[i]);
    for(int t = 0; t < 4; t++) for(int i = 0; i < 4; i++) s[i][n+t] = '.';
    for(int i = 0; i < n + 4; i++) for(int j = 0; j < 4; j++) if(s[j][i]=='*') sta[i] |= (1 << j);
    vi f(1<<12,INF);
    int initsta = (sta[0] << 8) | (sta[1] << 4) | sta[2];
    f[initsta] = 0;
    for(int i = 0; i <= n; i++){
        vi next_f(1<<12,INF);
        for(int msk = (1 << 8); msk < (1 << 12); msk++) cmin(next_f[0],f[msk]+c[3]);
        for(int msk = (1 << 12) - 1; ~msk; msk--){
            if(f[msk]==INF) continue;
            for(int pos = 0; pos < 4; pos++) for(int sz = 1; pos + sz <= 4; sz++){
                if(sz==4) continue;
                cmin(f[clear(msk,sz,pos)],f[msk]+c[sz-1]);
            }
        }
        for(int msk = 0; msk < (1 << 8); msk++) cmin(next_f[(msk<<4)|sta[i+3]],f[msk]);
        f.swap(next_f);
    }
    cout << f[0] << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

G. Yet Another Maxflow Problem

首先把最大流问题转化为最小割问题,那么可以发现左右两部分最多只会割掉一条边,假设左边割的边是(x ightarrow x+1),右边割的是(y ightarrow y+1),那么中间的边(i ightarrow j)(其中(i)为左半部分的点(j)为右半部分的点且(ile x,jge y+1))都是要割的

由于只有左半部分不是固定的,我们先考虑对于左半部分的每条割边,右半部分和中间连边的最小割,这个可以用线段树来动态维护,考虑从上到下枚举左半部分的割边,然后把对应的连着两部分的边的贡献加到线段树里面去,由于对于割边(y ightarrow y+1),只有(i ightarrow j,jge y+1)的边才是有用的,那么我们要求的其实就是一个后缀和的最大值,要求单点修改区间后缀最值查询,我们可以变成前缀修改,区间最值查询

现在对于每条左边的割边,右边割边的最值确定了,那么只要动态维护左边的最值就好了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "
"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
vi ca, cb;
vector<pii> G[MAXN];
struct SegmentTree{
    LL minn[MAXN<<2], lazy[MAXN<<2];
    int l[MAXN<<2], r[MAXN<<2];
    #define ls(rt) rt << 1
    #define rs(rt) rt << 1 | 1
    #define pushup(rt) minn[rt] = min(minn[ls(rt)],minn[rs(rt)])
    void pushdown(int rt){
        if(!lazy[rt]) return;
        lazy[ls(rt)] += lazy[rt]; lazy[rs(rt)] += lazy[rt];
        minn[ls(rt)] += lazy[rt]; minn[rs(rt)] += lazy[rt];
        lazy[rt] = 0;
    }
    void build(int L, int R, int rt = 1){
        l[rt] = L; r[rt] = R;
        if(L + 1 == R) return;
        int mid = (L + R) >> 1;
        build(L,mid,ls(rt)); build(mid,R,rs(rt));
    }
    void modify(int L, int R, LL x, int rt = 1){
        if(L>=r[rt] or l[rt]>=R) return;
        if(L<=l[rt] and r[rt]<=R){
            lazy[rt] += x; minn[rt] += x;
            return;
        }
        pushdown(rt);
        modify(L,R,x,ls(rt)); modify(L,R,x,rs(rt));
        pushup(rt);
    }
    LL qmin(int L, int R, int rt = 1){
        if(L>=r[rt] or l[rt]>=R) return INF;
        if(L<=l[rt] and r[rt]<=R) return minn[rt];
        pushdown(rt);
        return min(qmin(L,R,ls(rt)),qmin(L,R,rs(rt)));
    }
}STa,STb;
void solve(){
    int n, m, q;
    sci(n); sci(m); sci(q);
    ca.resize(n+1); cb.resize(n+1);
    for(int i = 1; i < n; i++) sci(ca[i]), sci(cb[i]);
    STa.build(1,n+1);
    STb.build(1,n+1);
    for(int i = 1; i <= n; i++) STa.modify(i,i+1,cb[i-1]);
    for(int i = 1; i <= m; i++){
        int u, v, w;
        sci(u); sci(v); sci(w);
        G[u] << make_pair(v,w);
    }
    for(int i = 1; i <= n; i++){
        for(auto p : G[i]) STa.modify(1,p.first+1,p.second);
        STb.modify(i,i+1,STa.qmin(1,n+1)+ca[i]);
    }
    cout << STb.qmin(1,n+1) << endl;
    while(q--){
        int x, w;
        sci(x); sci(w);
        STb.modify(x,x+1,w-ca[x]);
        ca[x] = w;
        cout << STb.qmin(1,n+1) << endl;
    }
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}
原文地址:https://www.cnblogs.com/kikokiko/p/13586070.html