Educational Codeforces Round 29

Educational Codeforces Round 29 

A. Quasi-palindrome

把后缀\(0\)去掉之后看一下串翻转之后和原串是否相同即可

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 "\n"
#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 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(){
    string s;
    cin >> s;
    while(!s.empty() and s.back()=='0') s.pop_back();
    if(s.empty()) cout << "YES" << endl;
    else{
        string t = s;
        reverse(all(t));
        if(t==s) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

B. Kayaking

枚举删掉的两个,剩下的排序贪心选即可

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 "\n"
#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 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<<1); for(int &x : A) sci(x);
    int ret = INT_MAX;
    for(int i = 1; i < (n << 1); i++) for(int j = 0; j < i; j++){
        vi vec;
        for(int k = 0; k < (int)A.size(); k++) if(k!=i and k!=j) vec << A[k];
        sort(all(vec));
        int tot = 0;
        for(int i = 1; i < (int)vec.size(); i+=2) tot += vec[i] - vec[i-1];
        cmin(ret,tot);
    }
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

C. 1-2-3

找循环节即可

可能先是一条链,再是循环

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 "\n"
#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 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;
int A[4][4], B[4][4];
int check(int x, int y){
    if(x==3){
        if(y==3) return 0;
        else if(y==2) return 1;
        else return -1;
    }else if(x==2){
        if(y==2) return 0;
        else if(y==1) return 1;
        else return -1;
    }else if(x==1){
        if(y==1) return 0;
        else if(y==3) return 1;
        else if(y==2) return -1;
    }
}
void solve(){
    LL k; int a, b;
    scl(k); sci(a); sci(b);
    for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) sci(A[i][j]);
    for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) sci(B[i][j]);
    map<pair<int,int>, bool> msk;
    vector<pair<int,int> > vec;
    vec << make_pair(a,b);
    msk[{a,b}] = true;
    while(true){
        int nexta = A[a][b], nextb = B[a][b];
        a = nexta, b = nextb;
        if(msk.count({a,b})) break;
        msk[{a,b}] = true;
        vec << make_pair(a,b);
    }
    vector<pair<int,int> > loop;
    int stpos = 0;
    for(int i = 0; ;i++) if(vec[i]==make_pair(a,b)){
        stpos = i;
        break;
    }
    for(int i = stpos; i < (int)vec.size(); i++) loop << vec[i];
    vector<pair<int,int> > v1, v2;
    for(int i = 0; i < (int)vec.size(); i++) {
        pii pre = i==0?make_pair(0,0):v1.back();
        int x = vec[i].first, y = vec[i].second;
        if(check(x,y)==1) v1 << make_pair(pre.first+1,pre.second);
        else if(check(x,y)==0) v1 << pre;
        else v1 << make_pair(pre.first,pre.second+1);
    }
    for(int i = 0; i < (int)loop.size(); i++){
        pii pre = i==0?make_pair(0,0):v2.back();
        int x = loop[i].first, y = loop[i].second;
        if(check(x,y)==1) v2 << make_pair(pre.first+1,pre.second);
        else if(check(x,y)==0) v2 << pre;
        else v2 << make_pair(pre.first,pre.second+1);
    }
    if(k<=vec.size()) cout << v1[k-1].first << ' ' << v1[k-1].second << endl;
    else{
        k -= vec.size();
        LL loops = k / loop.size();
        LL lft = k % loop.size();
        pll P = v1.back();
        P.first += loops * v2.back().first;
        P.second += loops * v2.back().second;
        if(lft){
            P.first += v2[lft-1].first;
            P.second += v2[lft-1].second;
        }
        cout << P.first << ' ' << P.second << endl;
    }
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

D. Yet Another Array Queries Problem

对每个位置单独操作,反向找初始位置即可

复杂度\(O(m\cdot q)\)

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 "\n"
#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 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;
int n, q, m;

void solve(){
    sci(n); sci(q); sci(m);
    vi A(n); for(int &x : A) sci(x);
    vector<pair<int,pii> > Q(q);
    for(auto &p : Q){
        sci(p.first), sci(p.second.first), sci(p.second.second);
        p.second.first--; p.second.second--;
    }
    reverse(all(Q));
    for(int i = 0; i < m; i++){
        int idx; sci(idx); idx--;
        for(auto &p : Q){
            int tp = p.first, l = p.second.first, r = p.second.second;
            if(idx<l or idx>r) continue;
            if(tp==1) idx = (idx==l ? r : idx-1);
            else idx = r - idx + l;
        }
        cout << A[idx] << ' ';
    }
    cout << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

E. Turn Off The TV

把坐标离散化,然后对每条线段覆盖的区间进行区间加\(1\)
用差分前缀和来做,然后把每个位置的覆盖次数算出来,如果大于等于\(2\)赋值\(1\),否则赋值\(0\)

枚举每条线段,判断这条线段覆盖的点是否都有超过两条线段覆盖即可

注意离散化的时候还要加入线段端点的左右端点,否则会有遗漏点没被考虑到

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 "\n"
#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 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);
    vector<pii> A(n); for(auto &p : A) sci(p.first), sci(p.second);
    vector<int> vec;
    for(auto &p : A) vec << p.first << p.second;
    sort(all(vec)); vec.erase(unique(all(vec)),vec.end());
    for(int i = 0, sz = vec.size(); i < sz; i++){
        vec << vec[i] - 1;
        vec << vec[i] + 1;
    }
    sort(all(vec)); vec.erase(unique(all(vec)),vec.end());
    for(auto &p : A){
        p.first = lower_bound(all(vec),p.first) - vec.begin() + 1;
        p.second = lower_bound(all(vec),p.second) - vec.begin() + 1;
    }
    vi presum(vec.size() << 1, 0);
    for(auto &p : A){
        presum[p.first]++;
        presum[p.second+1]--;
    }
    for(int i = 1; i < (int)presum.size(); i++) presum[i] += presum[i-1];
    for(auto &x : presum) x = (x>=2 ? 1 : 0);
    for(int i = 1; i < (int)presum.size(); i++) presum[i] += presum[i-1];
    for(int i = 0; i < (int)A.size(); i++){
        int l = A[i].first, r = A[i].second;
        if(presum[r] - presum[l-1] == r - l + 1){
            cout << i + 1 << endl;
            return;
        }
    }
    cout << -1 << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

F. Almost Permutation

先暴力把每个数可以在的区间找出来

然后费用流建图

可以发现每多出现一次同一个数,费用会额外加上\(c^2-(c-1)^2 = 2 \cdot c - 1\)

每个数字向汇点连\(n\)条边,每条边容量\(1\),费用分别为\(2\cdot c - 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 "\n"
#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 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 = 111;
int n, q, low[MAXN], high[MAXN];
int pre[MAXN], preid[MAXN], dist[MAXN], flow[MAXN];
bool vis[MAXN];
#define S 0
#define T MAXN - 1
struct EDGE{
    int to,cap,fee,rev;
    EDGE(){}
    EDGE(int _to, int _cap, int _fee, int _rev){
        to = _to; cap = _cap;
        fee = _fee; rev = _rev;
    }
};
vector<EDGE> G[MAXN];
void ADDEDGE(int u, int v, int cap, int fee){
    G[u].emplace_back(EDGE(v,cap,fee,(int)G[v].size()));
    G[v].emplace_back(EDGE(u,0,-fee,(int)G[u].size()-1));
}
bool spfa(){
    memset(dist,0x3f,sizeof(dist));
    dist[S] = 0;
    flow[S] = INF;
    memset(vis,0,sizeof(vis));
    queue<int> que;
    que.push(S);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        vis[u] = 0;
        for(int i = 0; i < (int)G[u].size(); i++){
            auto e = G[u][i];
            if(!e.cap or dist[e.to]<=dist[u]+e.fee) continue;
            dist[e.to] = dist[u] + e.fee;
            flow[e.to] = min(e.cap,flow[u]);
            pre[e.to] = u; preid[e.to] = i;
            if(!vis[e.to]){
                vis[e.to] = 1;
                que.push(e.to);
            }
        }
    }
    return dist[T]!=INF;
}
int mcmf(){
    int cost = 0;
    while(spfa()){
        int u = T;
        cost += dist[T] * flow[T];
        while(u!=S){
            int p = pre[u], id = preid[u];
            G[p][id].cap -= flow[T];
            G[u][G[p][id].rev].cap += flow[T];
            u = pre[u];
        }
    }
    return cost;
}
void solve(){
    sci(n); sci(q);
    for(int i = 1; i <= n; i++) low[i] = 1, high[i] = n;
    for(int i = 1; i <= q; i++){
        int tp, l, r, v;
        sci(tp); sci(l); sci(r); sci(v);
        if(tp==1) for(int j = l; j <= r; j++) cmax(low[j],v);
        else for(int j = l; j <= r; j++) cmin(high[j],v);   
    }
    for(int i = 1; i <= n; i++) if(low[i]>high[i]){
        cout << -1 << endl;
        return;
    }
    for(int i = 1; i <= n; i++){
        ADDEDGE(S,i,1,0);
        for(int j = low[i]; j <= high[i]; j++) ADDEDGE(i,j+n,1,0);
        for(int j = 1; j <= n; j++) ADDEDGE(i+n,T,1,2*j-1);
    }
    cout << mcmf() << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}
posted @ 2020-08-25 11:46  _kiko  阅读(104)  评论(0编辑  收藏  举报