AtCoder 초급 콘테스트 188 문제 해결 보고서

제목 링크 : https://atcoder.jp/contests/abc188/tasks

A-3 점 슛

이야기

x, y를주고 작은 값에 3을 더한 값이 더 큰 값을 초과 할 수 있는지 묻습니다.

아이디어

직접적인 판단

ac 코드

#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-직교성

이야기

두 배열, 해당 위치를 곱하고 합하여 0과 같은지 확인합니다.

아이디어

직접 시뮬레이션

ac 코드

#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 토너먼트

이야기

n과 i 번째 사람의 점수를 나타내는 2 ^ n 개의 숫자를 제공합니다. 각 라운드에는 서로 인접한 2 개의 pk가 있습니다. 점수가 더 높은 사람이 이기고 다음 라운드에 진입하여 이니셜을 출력합니다. 최종 2 위의 아래 첨자

아이디어

벡터 시뮬레이션

ac 코드

#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-스 누크 프라임

이야기

Takahashi가 놀러 나가서 지금 n 개의 아이템을 제공합니다. 시간은 [ai, bi]입니다.이 아이템들은 매일 ci를 소비해야하지만,이 날에 나오는 모든 아이템을 재생하기 위해 하루에 C 위안을 소비하도록 선택할 수 있습니다. , 그는 플레이해야하며, 최소한의 지출을 요청해야합니다.

예를 들어, 첫 번째 예에서는 2 개의 항목이 있으며 하루에 나타나는 모든 항목을 재생하는 데 6 개의 비용이 들며, 첫 번째 항목은 [1,2]에 나타나고, 하루에 4 개의 비용이 들며, 두 번째 항목은 [2,2], 4 일당 비용이 발생합니다. 즉, 첫날은 4, 다음날은 4 + 4 = 8을 소비해야하지만 8 <6은 프로젝트 1을 재생하기 위해 6 위안을 소비하도록 선택할 수 있습니다. 2이므로 총 4 + 6 = 10

아이디어

차이점은 당일 각 항목의 비용을 계산하는 것입니다. 그러면 일일 비용은 당일 비용과 C 중 더 작은 값입니다.

ac 코드

#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-행상 

이야기

첫 번째 라인 n, m은 n 개의 점과 m 개의 모서리를 나타냅니다.

두 번째 줄의 n ai는 그 시점의 금 가격을 나타냅니다.

다음 m 개 행은 모서리를 나타내고 각 모서리는 방향 모서리입니다. 여기서 xi는 yi보다 작아야합니다.

이제 그는 금을 사기 위해 한 지점을 선택한 다음 다른 지점으로 가서 금을 팔고 최대 이익을 추구해야합니다.

아이디어

대답은 반복적으로 토폴로지 순서로 나타납니다. dp [i]는 출처 지점 (저는 그 지점을 모릅니다)에서 지점 i까지가는 가장 저렴한 금 가격을 나타냅니다. 단방향 에지이기 때문에 점은 절대로 돌아 가지 않을 것입니다. 실행 후 선형 재귀 만 수행 한 다음 a [son] -dp [i]의 최대 값 만 업데이트하면됩니다. son은 i의 자식 노드입니다.

ac 코드

#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

이야기

두 개의 숫자 x, y를 주면 매번 각 숫자에 +1 또는 -1 또는 * 2를 수행 할 수 있으며 x를 y로 변경하는 데 필요한 작업 수를 최소한 물어볼 수 있습니다.

아이디어

메모리 검색, dfs (y)는 x를 y로 변경하는 데 필요한 단계 수를 나타냅니다.

구체적으로 코드보기

ac 코드

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

 

추천

출처blog.csdn.net/weixin_43911947/article/details/112447322