0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ABC382】AtCoder Beginner Contest 382【C++】

Posted at

コンテスト名

AtCoder プログラミングコンテスト2024(AtCoder Beginner Contest 382)

コンテストURL

開催日

2024/11/30 21:00-22:40


A: Daily Cookie

解法

  • もとから空き箱の個数と $D$ を足す
ABC382A.cpp
#include <iostream>
#include <string>
using namespace std;

int main(){
    int n, d;
    cin >> n >> d;

    string s;
    cin >> s;

    int cnt = 0;
    for(int i=0; i<n; i++){
        if(s[i]=='.'){
            cnt++;
        }
    }

    cout << cnt + d << endl;

    return 0;
}

B: Daily Cookie 2

解法

  • 問題文通りにシミュレーションする
  • 文字列 $S$ を右から順にたどり、 $D$ 個の @. に変換する
ABC382B.cpp
#include <iostream>
#include <string>
using namespace std;

int main(){
    int n, d;
    cin >> n >> d;

    string s;
    cin >> s;

    int cnt = 0;
    for(int i=n-1; i>=0; i--){
        if(s[i]=='@'){
            cnt++;
            s[i] = '.';
        }
        if(cnt==d){
            break;
        }
    }

    cout << s << endl;

    return 0;
}

C: Kaiten Sushi

解法

  • 二分探索
  1. 寿司をソートする方法
    • 寿司を美味しさの昇順にソートし、各人が仮に先頭にいた場合に、どの寿司を食べるかを記録する
    • 各人の並び順を考慮し、答えを求める
  2. 人をソートする方法
    • 自分より美食度が低い人が前にいる人は、寿司を食べられない
    • 美食度が単調減少になるように、寿司を食べられない人を無視する
    • lower_bound(greater<int>()) で美食度が初めて各寿司の美味しさ $B$ 以下になる人を探索する
ABC382C_1.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(){
    int n, m;
    cin >> n >> m;

    vector<int> A(n);
    vector<pair<int, int>> B;
    int b;
    for(int i=0; i<n; i++){
        cin >> A[i];
    }
    for(int i=0; i<m; i++){
        cin >> b;
        B.emplace_back(b, i);
    }

    sort(B.begin(), B.end());

    vector<int> V(n);
    for(int i=0; i<n; i++){
        int idx = lower_bound(B.begin(), B.end(), make_pair(A[i], 0)) - B.begin();
        V[i] = idx;
    }

    vector<int> ans(m, -1);
    int now = m - 1;
    for(int i=0; i<n; i++){
        if(V[i]>now){
            continue;
        }
        for(int j=V[i]; j<=now; j++){
            auto [bvalue, bidx] = B[j];
            ans[bidx] = i + 1;
        }
        now = V[i] - 1;
    }

    for(int i=0; i<m; i++){
        cout << ans[i] << '\n';
    }

    return 0;
}
ABC382C_2.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(){
    int n, m;
    cin >> n >> m;

    vector<int> A(n);
    vector<int> B(m);
    for(int i=0; i<n; i++){
        cin >> A[i];
    }
    for(int i=0; i<m; i++){
        cin >> B[i];
    }

    for(int i=1; i<n; i++){
        A[i] = min(A[i], A[i-1]);
    }

    vector<int> ans(m, -1);
    for(int i=0; i<m; i++){
        int idx = lower_bound(A.begin(), A.end(), B[i], greater<int>()) - A.begin();
        if(idx<n){
            ans[i] = idx + 1;
        }
    }

    for(int i=0; i<m; i++){
        cout << ans[i] << '\n';
    }

    return 0;
}

D: Keep Distance

解法

  • 再帰関数
  • $A_N \leqq M$ を満たせないものは枝刈りする
ABC382D.cpp
#include <iostream>
#include <vector>
using namespace std;

int n, m;
vector<vector<int>> ans;

void f(int cnt, vector<int> &A, int last){
    if(cnt==n){
        ans.push_back(A);
        return;
    }

    for(int i=last+10; i<=m-10*(n-cnt-1); i++){
        A.push_back(i);
        f(cnt+1, A, i);
        A.pop_back();
    }
}

int main(){
    cin >> n >> m;

    vector<int> first;
    f(0, first, -9);

    cout << ans.size() << endl;
    for(int i=0; i<ans.size(); i++){
        for(int j=0; j<n; j++){
            if(j){
                cout << " ";
            }
            cout << ans[i][j];
        }
        cout << '\n';
    }

    return 0;
}

E: Expansion Packs

解法

  • 期待値動的計画法 (DP)
  • 1 つのパックに入っているレアカードの枚数の確率分布を求める
    • $\text{dp1}[i][j]$ := $i$ 枚目までで $j$ 枚レアカードが出る確率
    • $\text{dp1}[i+1][j+1]$ += $\text{dp1}[i][j] \times \frac{\text{P}[i]}{100}$
    • $\text{dp1}[i+1][j]$ += $\text{dp1}[i][j] \times (1 - \frac{\text{P}[i]}{100})$
  • 開封するパックの個数の期待値を求める
    • $\text{dp2}[i]$ := レアカードが $X$ 枚から残り $i$ 枚の状態で、 $X$ 枚になるまでのパックの個数の期待値
    • $\text{dp2}[i] = 1 + \sum\limits_{j=0}^N \text{dp2}[\max (i-j, 0)] \times \text{dp1}[N][j]$
    • 両辺にある $\text{dp2}[i]$ を移項して、 $\text{dp2}[i] = \frac{1 + \sum\limits_{j=1}^N \text{dp2}[\max (i-j, 0)] \times \text{dp1}[N][j]}{1 - \text{dp1}[N][0]}$
ABC382E.cpp
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

int main(){
    int n, x;
    cin >> n >> x;

    vector<int> P(n);
    for(int i=0; i<n; i++){
        cin >> P[i];
    }

    vector<vector<double>> dp1(n+1, vector<double>(n+1));
    dp1[0][0] = 1;
    for(int i=0; i<n; i++){
        for(int j=0; j<i+1; j++){
            dp1[i+1][j+1] += dp1[i][j] * P[i]/100.0;
            dp1[i+1][j] += dp1[i][j] * (1 - P[i]/100.0);
        }
    }

    vector<double> dp2(x+1);
    for(int i=1; i<=x; i++){
        dp2[i] += 1;
        for(int j=1; j<=n; j++){
            dp2[i] += dp2[max(i-j, 0)] * dp1[n][j];
        }
        dp2[i] /= 1 - dp1[n][0];
    }

    printf("%.10f\n", dp2[x]);

    return 0;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?