Educational Codeforces Round 134 (Rated for Div. 2) (A~D) (simulation, construction, binary XOR)

A. Image

simulation

#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int main()
{
    int T;cin>>T;
    while(T--){
        mp.clear();char a,b,c,d;cin>>a>>b>>c>>d;
        mp[a]++;mp[b]++;mp[c]++;mp[d]++;
        int sum=0;int r=4;
        for (auto i:mp){
            if(i.second==1&&r!=1){sum++;r--;}
            if(i.second==2&&r!=2){sum++;r-=2;}
        }
        cout<<sum<<endl;
    }
    return 0;
}

The problem solution is done with set, which is simpler

#include<bits/stdc++.h>
using namespace std;
set<char>mp;
int main()
{
    int T;cin>>T;
    while(T--){
        mp.clear();
        char a,b,c,d;cin>>a>>b>>c>>d;
        mp.insert(a);mp.insert(b);mp.insert(c);mp.insert(d);
        cout<<(int)mp.size()-1<<endl;
    }
    return 0;
}

B. Deadly Laser

Idea: First of all, no matter how you go, the minimum number of steps is n+m-2, so it depends on the range covered by the laser blocking the road

There are 4 blocking methods

1. Block the lower left corner 2. Block the upper right corner 3. Block the vertical 4. Block the horizontal

code:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T;cin>>T;
    while(T--){
        int n,m,sx,sy,d;cin>>n>>m>>sx>>sy>>d;
        if(m-sy<=d&&n-sx<=d||sy-1<=d&&sx-1<=d||sy-1<=d&&m-sy<=d||sx-1<=d&&n-sx<=d)
             cout<<-1<<'\n';
        else cout<<(n+m-2)<<'\n';
    }
    return 0;
}

C. Min-Max Array Transformation

Note: the data range is 2e5, and the array will be TLE if it is too small

Ideas:

First of all, it is easy to find the smallest array, just find the number that is exactly equal to it;

To find the largest number, look at the rules of the sample. From n-1 to 0, if a[i] is greater than b[i-1], it means that b[i-1] cannot be a[i] and before The sum of numbers, so start from b[i-1] as the new beginning; otherwise, because the previous b[i] is greater than a[i], there is no limit, so you can choose the largest

#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005],d[200005];
int main()
{
    ios::sync_with_stdio(0);
    int T;cin>>T;
    while(T--){
        int n;cin>>n;
        int minn=999999999;int maxx=0;
        for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];
        int l=0;
        for(int i=0;i<n;i++){while(b[l]<a[i])l++;cout<<b[l]-a[i]<<" ";}
        cout<<'\n';
        l=n-1;
        for(int i=n-1;i>=0;i--){d[i]=b[l]-a[i];if(a[i]>b[i-1])l=i-1;}
        for(int i=0;i<n;i++)cout<<d[i]<<" ";cout<<'\n';
    }
    return 0;
}

Finding the truth from the front to the back is almost the same

#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int T;cin>>T;
    while(T--){
        int n;cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<n;i++)cin>>b[i];
        int l=0;
        for(int i=0;i<n;i++){while(b[l]<a[i])l++;cout<<b[l]-a[i]<<" ";}
        cout<<'\n';l=0;
        for(int i=0;i<n;i++){
            l=max(l,i);while(a[l+1]<=b[l]&&l+1<n)l++;cout<<b[l]-a[i]<<" ";
        }
        cout<<'\n';
    }
    return 0;
}

D. Maximum AND

Title: There are arrays a and b, the array c is obtained by XORing a and b, and the final value is the AND operation of the array c, find the largest value

Ideas:

method one:

It is known that the highest bit of the last value must be the position of 1 in each of the c arrays

Each position with 1 is made of 1 of array a and 0 of array b (or 0 of array a and 0 of array b)

Then you can set a number x, x and each a[i] above, and the result cc can only be displayed if there are 1 digits on x and a[i] have 1 digits at the same time

x and each of the above (inverted b[i]), the result dd is that only the digits with 1 on x and the digits with 1 at the same time (inverted b[i]) can be displayed

If cc and dd can be equal one-to-one, it means that the 1 of a[i] and the 0 of b[i] can correspond one-to-one (it is also the one-to-one correspondence between the 0 of a[i] and the 1 of b[i])

So when checking, you only need to judge whether cc and dd are equal.

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100005];int b[100005];int n;
int c[100005];int d[100005];
bool check(int x){
    for(int i=1;i<=n;i++)c[i]=a[i]&x;
    for(int i=1;i<=n;i++)d[i]=(~b[i])&x;
    sort(c+1,c+1+n);sort(d+1,d+1+n);
    for(int i=1;i<=n;i++){
        if(c[i]!=d[i])return 0;
    }
    return 1;
}
signed main()
{
    int T;cin>>T;
    while(T--){
        int coun=0;cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)cin>>b[i];
        int res=0;
        for(int i=31;i>=0;i--){
            if(check(res|(1<<i)))res=res|((1<<i));
        }
        cout<<res<<'\n';
    }
    return 0;
}

Method 2 (and search)

If the 1 part of a certain bit is paired with the 0 part of b, if the number is wrong, continue

If it is correct, match the 1 part of a with the 0 part of b from that part, if the number is wrong, then continue

But I haven't watched it yet...

Guess you like

Origin blog.csdn.net/zy98zy998/article/details/126997120