教育コードフォース ラウンド 134 (ディビジョン 2 の評価) (A ~ D) (シミュレーション、構築、バイナリ XOR)

A. 画像

シミュレーション

#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;
}

問題の解決は set で行われます。これはより簡単です。

#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. デッドリーレーザー

アイデア: まず、どのように進むにしても、最小歩数は n+m-2 であるため、道路を遮るレーザーがカバーする範囲によって決まります。

ブロック方法は4つあります

1. 左下隅をブロック 2. 右上隅をブロック 3. 垂直方向をブロック 4. 水平方向をブロック

コード:

#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 配列の変換

注: データ範囲は 2e5 で、小さすぎる場合、配列は TLE になります。

アイデア:

まず、最小の配列を見つけるのは簡単です。それに正確に等しい数値を見つけるだけです。

最大の数を見つけるには、サンプルの規則を見てください。n-1 から 0 まで、a[i] が b[i-1] より大きい場合、b[i-1] は a[i にはなり得ないことを意味します] とその前 数値の合計なので、新しい始まりとして b[i-1] から開始します。それ以外の場合は、前の b[i] が a[i] より大きいため、制限がないため、最大のものを選択できます

#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;
}

真実を見つけるのは前から後ろまでほとんど同じです

#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. 最大 AND

タイトル: 配列 a と b があり、配列 c は a と b の XOR 演算によって取得され、最終的な値は配列 c の AND 演算であり、最大値を見つけます

アイデア:

方法 1:

最後の値の最上位ビットは、各 c 配列の 1 の位置でなければならないことがわかっています。

1 の各位置は、配列 a の 1 と配列 b の 0 (または配列 a の 0 と配列 b の 0) で構成されます。

次に、上記の数値 x、x、および各 a[i] を設定できます。結果 cc は、x に 1 桁があり、a[i] に同時に 1 桁がある場合のみ表示されます。

x と上記のそれぞれ (反転 b[i]) の結果 dd は、x に 1 を含む数字と同時に 1 を含む数字(反転 b[i])のみを表示できることになります。

cc と dd が 1 対 1 に等しい場合、a[i] の 1 と b[i] の 0 は 1 対 1 に対応できることを意味します (また、 a[i] の 0 と b[i] の 1)

したがって、チェックするときは、cc と dd が等しいかどうかを判断するだけで済みます。

コード:

#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;
}

方法 2 (および検索)

特定のビットの 1 の部分が b の 0 の部分とペアになっている場合、数値が間違っている場合は続行します

正しい場合は、a の 1 の部分と、その部分の b の 0 の部分を一致させます。数値が間違っている場合は、続行します。

でもまだ見てないんですが…

おすすめ

転載: blog.csdn.net/zy98zy998/article/details/126997120