Codeforces Global Round 16 A-E Section Solutions

A-Median Maximization

meaning of the title

Given n n n n and s, find the maximum of the median if n numbers sum to s.

thinking

Check-in, greedy, the median is all zero in front, average in the back, if it's not an integer, then maximize it in the back

Code

The hidden part that was used at that time, because time is not waiting for people, the percentage of points is not considered as much.. Okay, it's my dish.

inline void Case_Test()
{
    cin>>n>>s;
    //if (n%2==1) n-=n/2;
    //else n-=(n-1)/2;
    n-=(n-1)/2;
    cout<<s/n<<endl;
}

B-MIN-MEX Cut

meaning of the title

MEX is the smallest number that does not appear. Give a 01 string to find the minimum MEX and how much it is.

thinking

We can see that if there is "01", then there is 2. That doesn't make sense. In fact, we can divide a "01" directly into "0" and "1", so the answer only contributes 1 (1+0), because MEX("1")=0, then we will divide 1 and see how many "01" there are, but we will take min(2,ans) at the end.Because the answer is only 2 at most, it can't be more than 2, because we choose nothing, select original string to 2, only 01, MEX(s)=2

Code

inline void Case_Test()
{
    cin>>s;
    l=s.length();
    ans=0;
    if (s[0]=='1') ans+=0,pre=1;
    else ans+=1,pre=0;
    //cout<<ans<<" "<<pre<<endl;
    for (int i=1;i<l;i++)
    {
        tmp=s[i]-'0';
        if (tmp==pre) continue;
        if (tmp==1) // tmp=0 
            ans+=0,pre=1;
        else //tmp = 1
            ans+=1,pre=0;
    }
    cout<<min(ans,2)<<endl;
}

C-MAX-MEX Cut

meaning of the title

Give a two-line string, much like B, that divides the original string into two-line substrings for maximum MEX and, well, roughly that.

thinking

This two rows are hard to beat, let's use latex. Let's just write it briefly. As in Question B, the comparison between one row and the next is almost as direct ans+=2 when we encounter a column of "01". Because of greed, asking for the largest MEX and then encountering the two rows of "2"... Then I did the following: the previous column is {00,01,11} and the next column is {00,01,11}There are three, three, nine, and then you can judge that you are probably greedy. For example, if the first column is "00" and the last column is "11", you can figure out two at this time, and then clear up (the specific operation is pre=-1).

However, note that if "00" encounters "01", I wa here, that is when the score is calculated, ans+=3, because it can be divided into two, the first "00" contribution is 1 and the second "01" contribution is 2.

Code

inline void Case_Test()
{
    int ans=0;
    cin>>n>>s1>>s2;
    for (int i=0;i<n;i++)
        a[i]=s1[i]+s2[i]-'0'-'0';
    pre=a[0];
    if (a[0]==1) ans+=2,pre=-1;
    //for (int i=0;i<n;i++) cout<<a[i]<<" ";
    //cout<<endl;
    for (int i=1;i<n;i++)
    {
        int t=a[i];
        //cout<<i<<" "<<a[i]<<" "<<pre<<endl;
        if (pre==-1) 
        {
            pre=t;
            if (t==1) pre=-1,ans+=2;
            continue;
        }
        if (pre==0)
        {   
            if (a[i]==0) ans+=1;
            if (a[i]==1) ans+=3,pre=-1;
            if (a[i]==2) ans+=2,pre=-1;
        }
        else if (pre==1)
        {
            ans+=2;
            pre=-1;
        }
        else if (pre==2)
        {
            if (a[i]==0||a[i]==1) ans+=2,pre=-1;
            else pre=2; 
        }
        //cout<<i<<" "<<ans<<endl;
    }
    if (pre==0) ans++;
    if (pre==1) ans+=2;
    //cout<<pre<<endl;
    cout<<ans<<endl;
}   

D1-Seating Arrangements (easy version)

meaning of the title

Give a n and m, in this title n=1, which is a simple version. Then there are n*m seats in total. Everyone has a vision value, and a person with small vision sits in front of them. Then ask what the inconvenience value is. The inconvenience value is that across the seats, everyone enters the seats in the order they are read in.

thinking

When n = 1 and M is only 300 at the maximum, then we can calculate how much is ahead by reading in. Direct violence is done in a two-tier cycle, with emphasis on Item 2 D2

Code

inline void Case_Test()
{
    cin>>n>>m;
    ans=0;
    for (int i=1;i<=n*m;i++)
    {
        cin>>a[i];
        for (int j=1;j<i;j++)
            if (a[i]>a[j]) ans++;
    }
    cout<<ans<<endl;
}

D2-Seating Arrangements (hard version)

meaning of the title

The meaning of the title is like D2, just look at the original title

thinking

Following the first question, let's think about the second question of violence, and then try to optimize the time complexity reduction. Let's go directly here.

Because of the minimum requirements, each entry sequence will enter a fixed position according to the simulation. If there are identical, the first entry will enter the back seat, because the next identical number will cross ta, ans++. So we use the structure and sort once (handwritten cmp)Get where everyone should be, and loop through to make further judgments.

struct node
{
    int v,pos;
}b[N];
int n,m,t,x,y;
struct carry
{
    int v,x,y;
}a[N];
int ans,tmp;
vector<int> v[301];
inline bool cmp(node x,node y)
{
    if (x.v==y.v) return x.pos<y.pos;
    return x.v<y.v;
}

Violence: A two-dimensional array a[i][j] denotes a location, fills it i n every person it enters, and then loops to simulate how many are i n front, such a time complexity is O(n^3), that's not very realistic, so let's reduce the time complexity. Because each row is in ascending order, we look at it in two, but if it's an array and it doesn't enter 0, it's not so good. So to change the container, the first thing I think about is set, set can be inserted, and it's ordered after insertion, but I don't know it can be...

set<int> s[n];

The vector s container I thought about behind me, but I couldn't insert them in order, so... I searched the Internet, so I could:

v[x].insert(lower_bound(v[x].begin() , v[x].end() , a[i].v) , a[i].v);

This allows us to simulate how many people in each v[x] (x stands for X rows/rows) can see. Each time we enter a person, we first extract which X rows it should be in, and then use a two-point (O(logn)) to determine where it is (how many are in front), so the total time complexity is O(Tn^2logn)

for (int i=1;i<=n*m;i++)
{
    x=a[i].x;
    tmp=lower_bound(v[x].begin() , v[x].end() , a[i].v)-v[x].begin();
    ans+=tmp;
    v[x].insert(lower_bound(v[x].begin() , v[x].end() , a[i].v) , a[i].v);
    //cout<<i<<" "<<tmp<<endl;
}

Code

#include<stack>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<deque>
#include<vector>
#include<iostream>
#include<map>
#include<unordered_map>
#include<set>
#include<iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define endl "\n"
#define debug(a) cout<<#a<<"="<<a<<endl;
#define eps 1e-8
using namespace std;
ll GCD(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int inf=0x3f3f3f3f;
const int N = 90007;
struct node
{
    int v,pos;
}b[N];
int n,m,t,x,y;
struct carry
{
    int v,x,y;
}a[N];
int ans,tmp;
vector<int> v[301];
inline bool cmp(node x,node y)
{
    if (x.v==y.v) return x.pos<y.pos;
    return x.v<y.v;
}
inline void Case_Test()
{
    cin>>n>>m;
    for (int i=1;i<=n*m;i++)
    {
        cin>>a[i].v;
        b[i].v=a[i].v;
        b[i].pos=i;
    }
    sort(b+1,b+1+n*m,cmp);
    x=n;y=m;
    for (int i=n*m;i>=1;i--)
    {
        t=b[i].pos;
        a[t].x=x;
        a[t].y=y;
        y--;
        if (y==0) y=m,x--;
    }
    //for (int i=1;i<=n*m;i++) cout<<a[i].v<<" "<<a[i].x<<" "<<a[i].y<<endl;
    ans=0;
    for (int i=1;i<=300;i++) v[i].clear();
    for (int i=1;i<=n*m;i++)
    {
        x=a[i].x;
        tmp=lower_bound(v[x].begin() , v[x].end() , a[i].v)-v[x].begin();
        ans+=tmp;
        v[x].insert(lower_bound(v[x].begin() , v[x].end() , a[i].v) , a[i].v);
        //cout<<i<<" "<<tmp<<endl;
    }
    cout<<ans<<endl;
}

signed main() 
{
    #ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
            clock_t start, end;
            start = clock();
    #endif
    IOS
    int _=1;
    cin>>_;
    while (_--)
    {
        Case_Test();
    }

    #ifndef ONLINE_JUDGE
        end = clock();
        cout << endl << "Runtime: " << (double)(end - start) / CLOCKS_PER_SEC << "s\n";
    #endif
}

E-Buds Re-hanging

meaning of the title

Given a tree, you can connect a bud to another vertex (the vertex can't be your own branch, it's actually a guarantee or a tree) and ask what the fewest leaf trees are after several operations.

thinking

Cao Lao: dfs find buds, leaves, other. Disconnect buds directly after finding buds. The answer is the number of leaves + other leaves - buds on the buds. Note the special root

Code

#include<stack>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<deque>
#include<vector>
#include<iostream>
#include<map>
#include<unordered_map>
#include<set>
#include<iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define endl "\n"
#define debug(a) cout<<#a<<"="<<a<<endl;
#define eps 1e-8
using namespace std;
ll GCD(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int inf=0x3f3f3f3f;
const int N = 2e5+1;
struct node
{
    int to,next;
}edge[N<<1|1];
int head[N],cnt;
inline void add(int x,int to)
{
    edge[++cnt].to=to;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
int u,v,n,num_ya,num_ye,ans;
inline int dfs(int x,int pre)
{
    bool ya=true;
    int cnt=0;
    for (int i=head[x];i;i=edge[i].next)
    {
        int y=edge[i].to;
        if (y==pre) continue;
        int t=dfs(y,x);
        //t=0 wu t=1 ye t=2 ya
        if (t==0) ya=false;
        if (t!=2) cnt++;
        //cout<<cnt<<" "<<num_ya<<" "<<num_ye<<" "<<ans<<endl;
    }
    //cout<<cnt<<" "<<num_ya<<" "<<num_ye<<" "<<ans<<endl;
    if (cnt&&ya&&x!=1) 
    {
        num_ya++;
        ans+=cnt;
        return 2;
    }
    //ya
    if (cnt==0&&x!=1) return 1;
    //ye
    if (x==1&&cnt==0) cnt++;
    //cout<<cnt<<" "<<num_ya<<" "<<num_ye<<" "<<ans<<endl;
    num_ye+=cnt;
    return 0;
    //wu
}
inline void Case_Test()
{
    cin>>n;
    memset(head,0,sizeof(head));
    for (int i=1;i<n;i++)
    {
        cin>>u>>v;
        add(u,v);add(v,u);
    }
    ans=0;num_ya=0;num_ye=0;cnt=0;
    dfs(1,-1);
    cout<<max(1,ans-num_ya+num_ye)<<endl;
}

signed main() 
{
    #ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
            clock_t start, end;
            start = clock();
    #endif
    IOS
    int _=1;
    cin>>_;
    while (_--)
    {
        Case_Test();
    }

    #ifndef ONLINE_JUDGE
        end = clock();
        cout << endl << "Runtime: " << (double)(end - start) / CLOCKS_PER_SEC << "s\n";
    #endif
}

F-Points Movement

* To be supplemented

summary

The score on this field is + 178, it will be 1500 immediately, and the trumpet is 1404, rushing!

Tags: Algorithm

Posted on Tue, 14 Sep 2021 13:06:59 -0400 by Thivya