AtCoder-Anfängerwettbewerb 188 Bericht zur Problemlösung

Titellink: https://atcoder.jp/contests/abc188/tasks

A - Dreipunktaufnahme

Thema

Geben Sie x, y an und fragen Sie, ob der kleinere Wert plus 3 den größeren Wert überschreiten kann

Ideen

Direktes Urteil

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    int x, y;
    cin >> x >> y;
    if(x > y) swap(x, y);
    if(x + 3 > y) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

B - Orthogonalität

Thema

Bei zwei Arrays werden die entsprechenden Positionen multipliziert und summiert, um festzustellen, ob sie gleich 0 sind

Ideen

Direkte Simulation

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int a[maxn], b[maxn];
int main(){
    int n; cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) cin >> b[i];
    ll ans = 0;
    for(int i = 1; i <= n; i ++) ans += a[i] * b[i];
    if(ans == 0) cout << "Yes" << endl;
    else cout << "No" << endl; 
    return 0;
}

C - ABC Turnier

Thema

Geben Sie ein n und dann 2 ^ n Zahlen, die die Punktzahl der i-ten Person darstellen. Jede Runde hat zwei nebeneinander liegende Punkte. Diejenige mit der höheren Punktzahl gewinnt, geht in die nächste Runde und gibt die Initiale aus Index des letzten Zweitplatzierten

Ideen

Vektorsimulation

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
vector<pair<int, int>> a, b;
int main(){
    int n; cin >> n;
    for(int i = 1; i <= (1 << n); i ++) {
        int x; cin >> x;
        a.push_back({x, i});
    }
    for(int i = 1; i < n; i ++){
        for(int j = 0; j < a.size(); j += 2){
            if(a[j].first > a[j + 1].first) b.push_back(a[j]);
            else b.push_back(a[j + 1]);
        }
        a = b;
        b.clear();
    }
    if(a[0].first > a[1].first) cout << a[1].second << endl;
    else cout << a[0].second << endl;
    return 0;
}

D - Snuke Prime

Thema

Takahashi ging zum Spielen aus und stellt nun n Gegenstände zur Verfügung. Die Zeit ist [ai, bi]. Diese Gegenstände müssen jeden Tag ci ausgeben, aber er kann C yuan pro Tag ausgeben, um alle Gegenstände zu spielen, die an diesem Tag erscheinen , er muss spielen, ihn bitten, am wenigsten auszugeben

Zum Beispiel gibt es im ersten Beispiel 2 Gegenstände, es kostet 6, um alle Gegenstände zu spielen, die an einem Tag erscheinen, der erste Gegenstand erscheint in [1,2], es kostet 4 pro Tag und der zweite Gegenstand erscheint in [2,2] kostet es pro Tag 4, was bedeutet, dass der erste Tag 4 ausgeben muss, der nächste Tag 4 + 4 = 8, aber 8 <6 können 6 Yuan ausgeben, um Projekt 1 zu spielen. 2, also insgesamt 4 + 6 = 10

Ideen

Die Differenz besteht darin, die Kosten für jeden Artikel am Tag zu berechnen. Die täglichen Kosten sind dann der kleinere Wert der Kosten des aktuellen Tages und C.

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
map<int, ll> mp; // 差分数组
//s表示差分的前缀和,表示到这天单付当天所有项目的花费
//last表示一个天数,(it.first - last)表示s价格出现的天数,也就是在这个期间价格不变
//x表示当天花的钱
//ans表示求的最小花费
int main(){
    ll n, c;
    cin >> n >> c;
    for(int i = 1; i <= n; i ++){
        ll x, y, w; 
        cin >> x >> y >> w;
        mp[x] += w; mp[y + 1] -= w; // 差分操作
    }
    ll s = 0, ans = 0;
    int last = 0;
    for(auto it : mp){
        ll x = min(s, c);
        ans += x * (it.first - last);
        s += it.second;
        last = it.first;
    }
    cout << ans << endl;
    return 0;
}

E - Hausierer 

Thema

Die erste Linie n, m repräsentiert n Punkte und m Kanten,

Das n ai in der zweiten Zeile repräsentiert den Goldpreis zu diesem Zeitpunkt.

Die nächsten m Zeilen stellen Kanten dar, jede Kante ist eine gerichtete Kante, wobei xi kleiner als yi sein muss

Jetzt muss er einen Punkt auswählen, um Gold zu kaufen, und dann zu einem anderen Punkt gehen, um Gold zu verkaufen, um maximalen Gewinn zu erzielen.

Ideen

Die Antwort ist rekursiv in der topologischen Reihenfolge, dp [i] repräsentiert den billigsten Goldpreis, der vom Quellpunkt (ich kenne diesen Punkt nicht) zum Punkt i geht. Weil es eine Einwegkante ist, dann dies Punkt wird definitiv nicht zurückgehen. Nur herunterlaufen, dann lineare Rekursion, und dann muss nur der Maximalwert eines [son] -dp [i] aktualisiert werden, son ist ein untergeordneter Knoten von i

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
int dp[maxn], in[maxn], a[maxn];
vector<int> v[maxn];
queue<int> q;
int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    while(m --){
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        in[y] ++;
    }
    for(int i = 1; i <= n; i ++){
        if(in[i] == 0) q.push(i);
        dp[i] = a[i]; //刚开始只初始化入度为0的节点然后wa了7个点,原因是存在2 3, 1 3种情况,也就是说这个图有可能是发散的,必须在跑到他之前就要初始化
    }
    int ans = -0x3f3f3f3f;
    while(q.size()){
        int t = q.front(); q.pop();
        for(auto it : v[t]){
            if(ans == -0x3f3f3f3f || ans < a[it] - dp[t]) ans = a[it] - dp[t];
            dp[it] = min(dp[it], dp[t]);
            if(--in[it] == 0) q.push(it);
        }
    }
    cout << ans << endl;
    return 0;
}

F - + 1-1x2

Thema

Geben Sie zwei Zahlen x, y an, Sie können jedes Mal +1 oder -1 oder * 2 für jede Zahl ausführen und Sie mindestens fragen, wie viele Operationen Sie benötigen, um x in y zu ändern

Ideen

Die Speichersuche dfs (y) gibt die Anzahl der Schritte an, die erforderlich sind, um x in y zu ändern

Siehe den Code speziell

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
map<ll, ll> dp; //dp[y]表示将x变成y需要的步数
ll x, y;
ll dfs(ll yy){
    if(yy <= x) return x - yy; //如果x大于等于yy,那么x只能进行x-yy次 减操作到达yy
    if(dp.count(y)) return dp[yy]; //记忆化操作直接返回
    ll res = yy - x; //表示x进行yy-x次 加操作到达y
    if(yy % 2 == 0) res = min(res, dfs(yy / 2) + 1); //如果yy是偶数,那么就存在乘2的操作,使得x到达yy
    else res = min(res, 1 + min(dfs(yy + 1), dfs(yy - 1))); //不然就看看加1减1操作使得x到达yy,取一个最小值
    return dp[yy] = res; //记忆化存
}
int main(){
    cin >> x >> y;
    cout << dfs(y);
    return 0;
}

 

Ich denke du magst

Origin blog.csdn.net/weixin_43911947/article/details/112447322
Empfohlen
Rangfolge