zafu individual 2022.2.16 A B C D E F G summary

Posted by Chrisww on Wed, 16 Feb 2022 13:39:09 +0100

zafu individual 2022.2.16 A B C D E F G summary

A - Three DiceAtCoder - abc202_a

Idea: sign in

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
signed main(){
    int a,b,c;
    cin>>a>>b>>c;
    int res=21;
    cout<<res-a-b-c<<endl;
    
    return 0;
}

B. Lineland Mail(900 points) CodeForces - 567A

Tip : greedy,implementation

Idea: obviously, the nearest one is its adjacent two numbers, and the farthest one is the first and last one m a x max max. Judge the boundary a little and simulate it.

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=1e5+10;
int a[N];
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int l=a[1];
    int r=a[n];
    for(int i=1;i<=n;i++){
        if(i==1)cout<<a[2]-a[1]<<' ';
        else if(i==n)cout<<abs(a[i-1]-a[i])<<' ';
        else{
            cout<<(min(a[i]-a[i-1],a[i+1]-a[i]))<<' ';
        }
        cout<<max(abs(l-a[i]),r-a[i])<<endl;
    }
    return 0;
}

B. Code obfuscation(1100 points) CodeForces - 765B

Tip : implementation ,string

Idea: I didn't understand what it was saying at first, but later I found that it was good to scan it again. At first, I started from a a a start, if so a a a. The upper limit is raised to b b b. If the character is higher than the upper limit, it indicates that it is not standardized.

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
signed main(){
    bool ok=true;
    char st='a';
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
        if(s[i]==st){
            st++;
        }
        else if(s[i]<st){
            continue;
        }
        else if(s[i]>st){
            ok=false;
            break;
        }   
    }
    if(ok)cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

D. Restoring Painting(1400 points) CodeForces - 675B

Tip : constructive algorithms,math

Idea: this question is a little difficult at the beginning. At the beginning, I thought it was wrong to discuss it by classification. Because the middle number pair 4 4 All four corners contribute, so they must be provided n n n schemes, then the rest only need to be counted 4 4 A combination of four corners. Because the number we choose must be 1 1 1 ~ n n n, so we just need to take one on both sides and in each corner m a x max max and m i n min min. Then the number of schemes will be m i n min min reduced to 1 1 1, m a x max max with m i n min min decreases at the same time. Then the range of the final alternative is m a x max max ~ n n n. The final number of options is ( n − m a x ) ∗ n . (n-max)*n. (n−max)∗n. consider m a x > n max>n In the case of Max > N, the number of schemes is 0 0 0.

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
signed main(){
    int n,a,b,c,d;
    cin>>n>>a>>b>>c>>d;
    int res[5];//Count the sum of the two sides of the four corners
    res[0]=a+b;
    res[1]=b+d;
    res[2]=c+d;
    res[3]=c+a;
    sort(res,res+4);
    int x=res[3]-res[0];//When the minimum decreases to 0, max decreases the final value.
    x++;
    if(x>n){
        cout<<0<<endl;
    }
    else{
        int sum=n-x+1;//The number of schemes under four corner constraints.
        cout<<sum*n<<endl;
    }
    return 0;
}

E. Hard Process(1600 points) CodeForces - 660C

Tip: two pointers

Idea: I didn't see that it was a double pointer at the beginning. Go to d f s dfs dfs and d p dp dp direction thought, seems to be OK d p ? dp? dp? But the double pointer is still very easy to think of and write. There is too little practice and it has been adjusted for a long time. Use one l l l and one r r r maintenance interval, if magic times k k When k is not enough, keep moving the left boundary to the right and narrow the range until k k k is not 0 0 0, and continuous recording is required 1 1 The left and right boundaries of the interval when the number of 1 is the largest. Finally, all numbers in this interval need to be changed 1 1 1 output. If k k k is 0 0 0 we can output it directly and return it.

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=3e5+10;
int a[N];
signed main(){
    int n,k;
    cin>>n>>k;
    int ma=0;//Count the maximum number of 1
    int ll,rr;//Used to record the left and right boundaries of the maximum continuity
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    if(k==0){
        int res=0;
        for(int i=1;i<=n;i++){
            if(a[i]==1){res++;}
            else if(a[i]==0){
                res=0;
            }
            ma=max(ma,res);
        }
        cout<<ma<<endl;
        for(int i=1;i<=n;i++)cout<<a[i]<<' ';
        cout<<endl;
        return 0;
    }
    int l,r;
    l=r=0;
    int res=0;
    for(int i=1;i<=n;i++){
        if(a[i]==1){//If it is 1, you can directly move to the right without consuming magic times
            r++;
        }
        else if(a[i]==0){
            if(res<k){//If the magic number is shifted to the right, it will cost 1 magic number
                res++;
                r++;
            }
            else if(res>=k){//If the magic number is not enough, move the left boundary to the right.
                while(l<r){
                    if(a[l+1]==0){
                        res--;
                        l++;
                    }
                    else if(a[l+1]==1){
                        l++;
                    }
                    if(res<k)break;
                }
                if(res<k){//If you get the magic number by shifting the left boundary to the left, you can consume 1 magic number and change the current 0 to 1
                    res++;
                    r++;
                }
            }
        }
        if(r-l>ma){//Compare updates
            ma=r-l;
            ll=l,rr=r;
        }
    }
    cout<<ma<<endl;
    for(int i=1;i<=ll;i++)cout<<a[i]<<' ';
    for(int i=ll+1;i<=rr;i++)cout<<1<<' ';//The interval is 1, and other outputs are the same.
    for(int i=rr+1;i<=n;i++)cout<<a[i]<<' ';
    cout<<endl;
    return 0;
}

F. Restore Permutation(1900 points) CodeForces - 1208D

Tip: Binary Indexed Tree,segment tree

Idea: it feels like a board question of tree array and line segment tree, O ( l o g n ) O(logn) O(logn) find interval sum and use. First, the last number must be unique and definite. We just need O ( n ) inverted PUSH O(n) Backstepping O(n) push back, each time O ( l o g n ) ∗ O ( l o g n ) O(logn)*O(logn) O(logn) * O(logn), dichotomy + query interval sum can confirm the subscript of the current number. After determining a number each time, delete the number in the tree array or line segment tree without affecting the interval and acquisition of subsequent operations. Total complexity O ( n ∗ l o g n ∗ l o g n ) O(n*logn*logn) O(n∗logn∗logn). Each scan only needs to save the binary answer coordinates + 1 +1 +1 can be stored in the container, because the question requires the sum of the numbers smaller than it in front, so its number is the answer coordinate + 1 +1 +1. The upward thinking is still very simple. I quickly pushed it out, and the result is good d e b u g debug debug more than an hour, there is a very pit point to pay attention to. If a [ i ] = = 0 And l = = 1 a[i]==0 and l==1 When a[i]==0 and l==1, if you only follow the above method, you cannot determine whether the current subscript is valid or not + 1 +1 +1. Because we can't determine the final coordinates 1 1 1 or 2 2 2. Because 1 1 This coordinate is very special. He is 2 2 The sum of the preceding numbers of 2 is also 1 1 1 itself. So let's judge if 1 1 If you haven't chosen yet, choose 1 1 1. Otherwise, if 1 1 If you choose, the final subscript must be 2 2 2. Use one b o o l bool bool can judge. It's not hard to think about this now, but it's been debug ged for a long time

  • Reference code (tree array version):
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=2e5+10;
int tr[N];
int a[N];
int n;
void add(int a,int x){
    for(int i=a;i<=n;i+=lowbit(i)){
        tr[i]+=x;
    }
}
int ask(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i)){
        res+=tr[i];
    }
    return res;
}
signed main(){
    cin>>n;
    vector<int>S;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        add(i,i);//All numbers are saved in the tree
    }
    bool ok1=true;//Judge whether 1 has been selected
    for(int i=n;i>=1;i--){
        int l=1;int r=n;
        while(l<r){
            int mid=l+r+1>>1;
            int x=ask(mid);
            if(x>a[i])r=mid-1;
            else l=mid;
        }
        if(a[i]==0&&l==1){
            if(ok1){
                ok1=false;
                add(1,-1);
                S.push_back(1);
            }
            else{
                add(2,-2);
                S.push_back(2);
            }
        }
        else{
            l=l+1;
            add(l,-l);
            S.push_back(l);
        }
    }
    reverse(S.begin(),S.end());//S[0] is the number of tails, so we have to turn it over.
    for(auto x:S)cout<<x<<' ';
    cout<<endl;
    return 0;
}

G. Ryouko's Memory Note(1800)CodeForces - 433C

Tip: math ,sorting

Idea: each number from x x x becomes y y Only the absolute value of the subtraction of y from its adjacent number changes and contributes to the of the answer. So we need O ( n ) O(n) O(n) scan, save the number adjacent to each number, and then if this number x x x has changed, so these numbers will be right y y The choice of y plays a vital role. last O ( n ) O(n) O(n) scan, from 1 1 1 to n n n make replacement selection. If the current number has no adjacent number, we will skip it directly, because its change will not affect the decision of the answer. Otherwise, we need to select a median from all adjacent numbers (which can be repeated) as y y y. Greedy: refer to warehouse location for details. Therefore, you need to make a change in the stored array s o r t sort sort, so the final complexity is O ( n l o g n ) O(nlogn) O(nlogn), then compare the contribution to the answer before and after the change, and record the largest contribution before the change − - − the changed value, then the last maximum value is the maximum value we can save. The final answer is the original energy cost minus the maximum energy savings.

  • Reference code:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=1e5+10;
int a[N];
vector<int>b[N];//Used to save data
signed main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>a[i];
    for(int i=1;i<=m;i++){
        if(i!=m){
            if(a[i]!=a[i+1])
            b[a[i]].push_back(a[i+1]);
        }
        if(i!=1){
            if(a[i]!=a[i-1])
            b[a[i]].push_back(a[i-1]);
        }
    }
    int sum=0;
    for(int i=2;i<=m;i++){
        sum+=abs(a[i]-a[i-1]);
    }
    int ma=0;//Save the most
    for(int i=1;i<=n;i++){
        if(b[i].size()==0)continue;//If there is no saved number to skip, it will not contribute to the answer.
        sort(b[i].begin(),b[i].end());
        int y=b[i][(b[i].size()-1)>>1];//median
        int before,after;
        before=after=0;
        for(auto x:b[i]){
            before+=abs(i-x);
            after+=abs(y-x);
        }
        ma=max(ma,before-after);//Update maximum savings
    }
    cout<<sum-ma<<endl;//Final minimum energy cost
    return 0;
}

Cut it 1900 1900 The 1900 question is still very happy, although c f cf cf competition may not have enough time, which is a small progress.

Topics: C C++