CF1287 div2 problem solution

Foreword

Last night fight CF div2, thinking things up points. However, the brain is not on-line, BC problems are linked, only two A.
Close-up Cipian to remember this shame.

All questions face the question: https://codeforces.com/contest/1287/problems

A. Angry Students

Surface problem: https://codeforces.com/contest/1287/problem/A
Solution: direct sweeping over the recording \ (A \) longest rear section \ (P \) can.
Time complexity: \ (O (n-) \) .
Code: Slightly

B. Hyperset

Surface problem: https://codeforces.com/contest/1287/problem/B
Solution:
can be found for any pair of cards, a card can, and they form a unique group.
Enumerate all the violence card, the information is stored in the map, you can look directly.
Time complexity: O ( \ (n-2 ^ \) klogn)
Code:

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define F(x,y,z) for(re x=y;x<=z;x++)
#define FOR(x,y,z) for(re x=y;x>=z;x--)
typedef long long ll;
#define I inline void
#define IN inline int
#define C(x,y) memset(x,y,sizeof(x))
#define STS system("pause")
template<class D>I read(D &res){
    res=0;register D g=1;register char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')g=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    res*=g;
}
map<string,int>mp;
string s;
char c[2020][110],t[110];
int n,m;
ll ans;
I Match(int x,int y){
    F(i,1,m){
        if(c[x][i]==c[y][i])t[i]=c[x][i];
        else {
            if(c[x][i]=='S'&&c[y][i]=='E')t[i]='T';
            else if(c[x][i]=='S'&&c[y][i]=='T')t[i]='E';
            else if(c[x][i]=='E'&&c[y][i]=='S')t[i]='T';
            else if(c[x][i]=='E'&&c[y][i]=='T')t[i]='S';
            else if(c[x][i]=='T'&&c[y][i]=='S')t[i]='E';
            else t[i]='S';
        }
    }
    s.clear();s.append(t+1);
}
int main(){
    //cin>>t+1;s.append(t+1);
    //F(i,0,s.size()-1)cout<<s[i];
    //return 0;
    read(n);read(m);
    F(i,1,n)cin>>c[i]+1;
    F(i,1,n-1){
        F(j,i+1,n){
            Match(i,j);
            if(!mp.count(s))continue;
            ans+=mp[s];
        }
        s.clear();s.append(c[i]+1);mp.insert(make_pair(s,1));
    }
    cout<<ans;
    return 0;
}

C. Garland

Questions surface: https://codeforces.com/contest/1287/problem/C
Solution: Consider DP.
Set \ (f [i] [j ] [k] [0/1] \) representing the forward considered \ (I \) bit, already put in place of the 0 \ (J \) even number
, \ (K \ ) th odd minimum cost. The current sub-transfer equation is not the place to discuss 0.
Time complexity: O ( \ (n-^. 3 \) )
This is sufficient by this question (I was too dishes), To consider how to optimize.
Found \ (I \) is determined, \ (J + K \) is a fixed value. So we can put \ (j, k \) squeezed into a variable.
Time complexity: O ( \ (^ n-2 \) )
Code:

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define F(x,y,z) for(re x=y;x<=z;x++)
#define FOR(x,y,z) for(re x=y;x>=z;x--)
typedef long long ll;
#define I inline void
#define IN inline int
#define C(x,y) memset(x,y,sizeof(x))
#define STS system("pause")
I read(int &res){
    res=0;re g=1;register char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')g=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    res*=g;
}
int n,m,a[110],v[110],s[110],f[110][110][2],A,B;
int main(){
    read(n);
    F(i,1,n){
        read(a[i]);s[i]=s[i-1];
        if(!a[i])a[i]=-1,s[i]++;
        else v[a[i]]=1,a[i]&=1;
    }
    F(i,1,n){
        if(!v[i]){
            if(i&1)B++;else A++;
        }
    }
//  F(i,1,n)cout<<a[i]<<" ";
    //cout<<endl;
    C(f,63);
    f[0][0][0]=0;f[0][0][1]=0;
    if(a[1]!=-1){
        F(j,0,min(s[1],A))if(s[1]-j<=B)f[1][j][a[1]]=min(f[0][j][0],f[0][j][1]);
    }
    else{
        F(j,0,min(s[1],A)){
            if(s[1]-j>B)continue;
            if(j)f[1][j][0]=min(f[0][j-1][0],f[0][j-1][1]);
            f[1][j][1]=min(f[0][j][0],f[0][j][1]);
        }
    }
    F(i,2,n){
        if(a[i]!=-1){
            F(j,0,min(s[i],A))if(s[i]-j<=B)f[i][j][a[i]]=min(f[i-1][j][0]+a[i],f[i-1][j][1]+(a[i]^1));
            continue;
        }
        F(j,0,min(s[i],A)){
            if(s[i]-j>B)continue;
            if(j)f[i][j][0]=min(f[i-1][j-1][0],f[i-1][j-1][1]+1);
            f[i][j][1]=min(f[i-1][j][0]+1,f[i-1][j][1]);
        }
    }
    //F(i,1,n)F(j,0,min(s[i],A))cout<<i<<" "<<j<<" "<<f[i][j][0]<<" "<<f[i][j][1]<<endl;
    cout<<min(f[n][A][0],f[n][A][1]);
    return 0;
}

D. Numbers on Tree

Questions surface: https://codeforces.com/contest/1287/problem/D
Solution: Consider solve the problem from the bottom up.
Each operation, we can point value in the current node in the subtree are added to a pile,
to find the position of the current boundary nodes \ (a [i] \) assigned to and behind the corresponding point value + 1.
But this is wrong, because it is possible in a single operation, such an addition operation may change the
size of the point in the relationship before the sub-tree. Consider how to avoid this problem.
It can be shown that, if a solution, there must be a solution, so that all points \ (a [i] \) are not the same.
Therefore, we can record what the maximum heap last time, next time give value to all points plus the maximum, and then into the reactor.
Time complexity: O ( \ (n-2 ^ \) logN)
Code:

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define F(x,y,z) for(re x=y;x<=z;x++)
#define FOR(x,y,z) for(re x=y;x>=z;x--)
typedef long long ll;
#define I inline void
#define IN inline int
#define C(x,y) memset(x,y,sizeof(x))
#define STS system("pause")
I read(int &res){
    res=0;re g=1;register char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')g=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    res*=g;
}
typedef pair<int,int>pii;
priority_queue<pii>q;
vector<int>e[2020];
int n,m,root,tot,bas,dep[2020],fa[2020],c[2020],w[2020];
pii b[2020];
I D_1(int x,int d){
    dep[x]=d;q.emplace(make_pair(d,x));
    for(auto p:e[x])D_1(p,d+1);
}
I D_2(int x){
    w[x]+=bas;
    b[++tot]=make_pair(w[x],x);
    for(auto p:e[x])D_2(p);
}
int main(){
    read(n);
    F(i,1,n)read(fa[i]),read(c[i]);
    F(i,1,n)if(!fa[i])root=i;else e[fa[i]].emplace_back(i);
    D_1(root,1);
    while(!q.empty()){
        m=q.top().second;q.pop();tot=bas=0;
        for(auto p:e[m]){
            D_2(p);sort(b+1,b+1+tot);bas=b[tot].first;
        }
        if(tot<c[m]){cout<<"NO";return 0;}
        sort(b+1,b+1+tot);w[m]=b[c[m]].first+1;
        F(i,c[m]+1,tot)w[b[i].second]++;
    }
    cout<<"YES"<<endl;
    F(i,1,n)cout<<w[i]<<" ";
    return 0;
}

E Madhouse

Questions surface: https://codeforces.com/contest/1287/problem/D
Solution: First, consider the simple version.
We can ask \ ([1, n] \ ) and \ ([1, the n-1-] \) .
The first inquiry found that more than the second time \ (n \) strings, which \ (n \) strings happens to be
the string \ (n \) suffix of a scrambled version. Find the \ (n \) strings can restore an entire string.
Queries: O ( \ (the n-^ 2 \) )

Guess you like

Origin www.cnblogs.com/Purple-wzy/p/12160709.html