Educational Codeforces Round 85(Div。2の評価)【ABCDE】(题解)

ディレクトリ

対象となる知識ポイント:思考、貪欲、数学。

ゲームへのリンク:ポータル

A-レベル統計

トピック:ゲームの数と通関手続きの数を時系列で示し、妥当かどうかを判断します。
解決策:隣接する間隔と合計間隔の回数が通関手続きの回数以上で、減少していないことを確認してください。
コードを受け入れる:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int maxp=0,maxc=0;
        bool flag=true;
        while(n--){
            int p,c;
            cin>>p>>c;
            if(p<maxp||c<maxc||p<c||p-maxp<c-maxc){
                flag=false;
            }
            maxp=max(p,maxp),maxc=max(c,maxc);
        }
        puts(flag?"YES":"NO");
    }
    return 0;
}

B-中流階級

トピック:富が特定のしきい値以上の富裕層であること規定するために、各操作で多数の人々を選択できるため、それぞれの富が平均になります。
問題の解決策:大きいものから小さいものに並べ替えた後に貪欲です。
コードを受け入れる:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll a[maxn];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        ll x;
        cin>>n>>x;
        for(int i=1;i<=n;i++)cin>>a[i];
        sort(a+1,a+n+1);
        reverse(a+1,a+1+n);
        int cnt=0;
        ll sum=0;
        for(int i=1;i<=n;i++){
            sum+=a[i];
            if(sum>=x*i)cnt++;
            else break;
        }
        cout<<cnt<<"\n";
    }
    return 0;
}

C-モンスターの輪

トピック:モンスターの輪があり、各モンスターのヘルス\(a_i \)であり、すべてのモンスターヒットは1ヘルスを失い、モンスターが死亡すると、次のモンスターに\(b_i \)ダメージを与えます。すべてのモンスターを破壊するために必要なショット数。
解決策:最初に前のモンスターの死によって引き起こされるであろうダメージまですべての血を修復し、次にモンスターを殺すために最小のダメージを選択します。
コードを受け入れる:回転の使い方学びました。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn],b[maxn];
int main(){
    int t;
    cin>>t;
    while(t--){
        ll n,ans=inf,cnt=0;
        scanf("%lld",&n);
        for(int i=0;i<n;i++)scanf("%lld%lld",&a[i],&b[i]);
        rotate(b,b+n-1,b+n);
        for(int i=0;i<n;i++){
            if(a[i]>b[i])cnt+=a[i]-b[i];
        }
        for(int i=0;i<n;i++){
            ll res=0;
            if(a[i]>b[i])res-=(a[i]-b[i]);
            res+=a[i];
            ans=min(ans,res);
        }
        cout<<cnt+ans<<"\n";
    }
    return 0;
}

D-最小オイラーサイクル

トピック:与えられた\(n \)個の頂点を持つ完全な有向グラフ。最小の辞書式順序でオイラーループの特定の間隔を見つける必要があります。
解決策:タイトルに示されている\(n = 3 \)の例を見ると、\(\ left [1,2,1,3 \ right] \ left [2,3 \ right] \ left [1 \ right ] \)
のためにその手段1(\ \ SIM N \)各ノードについて、辞書式に最小の現在の点から戻ってくるたびに順番に次のノードに移動を開始し、現在のポイントが、移動\(N- \)場合戻ることができない場合は、直接次のノードに移動する必要があります。そうしないと、移動する方法がありません。最後に、1つのノードに戻ります。
観察により、\(1 \ sim n \)ノードの場合、各グループには\(2(ni)\)ノードがあり、奇数番号のノード自体があり、偶数番号のノードが現在のグループにあることがわかります位置は\(2 + i \)で除算されます。
コードを受け入れる:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main(){
    int t;
    cin>>t;
    while(t--){
        ll n, l, r;
        cin>>n>>l>>r;
        ll limit = 1ll * n * (n - 1) + 1;
        ll sum = 0, id = 1;
        for (ll i = l; i <= r && i < limit; i++){
            while (sum + (n - id) * 2 < i)
                sum += (n - id) * 2, id++;
            ll d = i - sum;
            printf("%lld ", (d & 1) ? id : d / 2 + id);
        }
        if (r == limit)
            cout<<"1 ";
        cout<<"\n";
    }
}

E-除数パス

トピック:
正の整数\(D \)が与えられた場合、これを使用して画像を作成します

  1. 各ノードは\(D \)の因数です
  2. \(x、y(x> y)\)\(y \)\(x \)の因数あり、\(\ frac(x)(y)\)が素数の場合、ノード間に無向エッジがあります
  3. \(X、Y \)右辺間のエッジがある場合\(X \)因子ではない\(Y \)因子の数
    、所与の\(Q \)グループ照会要求\(U 、v \)最短パスの数

解決策:まず、いくつかの要因を投げて、ノード\(u \)を別のノード\(v \)に転送するプロセスを考えることができます。ここで、\(v | u \)
はuuからvvです最短パスは\(d(u)-d(x_1)+ d(x_1)-d(x-2)+ \ ldots + d(x_y)-d(v)= d(u)-d(v)\ )、ここで\(d(x)\)\(x \)の因子数であるため、ノードがノードで割り切れる場合、2つのノード間の最短経路は2つのノードの因子の数の差になります。\(u \)\(v \)の関係が倍数でないことを考えると、ノードの転送はいくつかの要因をスローすることによって実現する必要があるため、\(u- )になるように中間ノード\(x \)を見つける必要があります。> x \)\(v-> x \)、そして明らかに\(x \)\(u \)\(v \)の共通因子でなければならない、最短経路は\(d(u )-d(x)+ d(v)-d(x)\)最小、それから\(d(x)\)を最大にすることなので、\(x = gcd(u、v)\)、最後に請う\(g(u、gcd(u、v))* g(v、gcd(u、v))\)、ここで\(g(u、v)\)\(u \)\(v \ ) 2点間の最短経路の数
ノード\(u \)から別のノード\(v \)へのノードは常にいくつかの要素をスローすることによって実行されるため、これらの数はこれらの中間要素のスローです順不同、次に\(g(u、v)\)の場合、ここで\(v | u \)\(x = \ frac {u} {v} \)、次に\(g(u、v) = \ frac {t!} {p_1!* p_2!... p_n!} \)、ここで\(t \)\(x \)の素因数のべき乗の合計、\(p_i \)\ (x \)の素因数のべき乗は、順列と組み合わせにおける反復消去問題の階乗許容コードです

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
map<ll, ll> m;

ll calc(ll x){
    if (m[x])
        return m[x];
    ll res = 0, y = x;
    for (ll i = 2; i * i <= y; i++)
        if (y % i == 0){
            while (y % i == 0)
                y /= i;
            res = (res + calc(x / i)) % mod;
        }
    if (y > 1)
        res = (res + calc(x / y)) % mod;
    return m[x] = res;
}

int main(){
    ll d, q;
    cin>>d>>q;
    m[1] = 1;
    while (q--){
        ll u, v;
        cin>>u>>v;
        ll w = __gcd(u, v);
        printf("%lld\n", calc(u / w) * calc(v / w) % mod);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/charles1999/p/12683617.html