AtCoder abc323 参加メモ

UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323) - AtCoder

B - Round-Robin Tournament

それぞれ勝った回数をカウントして、回数の多い順に sort する。

勝ち数が同じ場合には番号の早い順となるため注意。

#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define endl '\n'
using P = pair<int,int>;

int main() {
  int n; cin >> n;
  vector<int> cnt(n);
  REP(i,n) {
    string s; cin >> s;
    REP(j,n) if (s[j] == 'o') cnt[i]++;
  }

  vector<P> p(n);
  REP(i,n) p[i] = { cnt[i], -(i+1) }; // 勝ち数が同じ場合は番号の早い順
  sort(p.rbegin(),p.rend());

  for(auto [_,v]: p) cout << -v << " ";
  return 0;
}

C - World Tour Finals

他のプレイヤーの総合得点を上回るまで、貪欲に得点の高い問題から解いていけば良い。

#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define endl '\n'
using P = pair<int,int>;

int main() {
  int n,m; cin >> n >> m;
  vector<int> a(m);
  vector<string> s(n);
  REP(i,m) cin >> a[i];
  REP(i,n) cin >> s[i];

  vector<int> score(n);
  REP(i,n) {
    REP(j,m) if (s[i][j] == 'o') score[i] += a[j];
    score[i] += (i+1);
  }

  vector<P> p(m);
  REP(i,m) p[i] = {a[i],i};
  sort(p.rbegin(),p.rend());
  vector<int> order(m);
  REP(i,m) order[i] = p[i].second;

  int mx = *max_element(score.begin(),score.end());
  REP(i,n) {
    int ans = 0;
    for(auto j: order) {
      if (score[i] >= mx) break;
      if (s[i][j] == 'o') continue;
      score[i] += a[j];
      ans++;
    }
    cout << ans << endl;
  }
  return 0;
}

D - Merge Slimes

貪欲にサイズの小さいスライムから合成していく

#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define endl '\n'
using ll = long long;

int main() {
  int n; cin >> n;
  map<ll,ll> mp;
  REP(i,n) {
    int s,c; cin >> s >> c;
    mp[s] += c;
  }

  int ans = 0;
  for(auto [size,cnt]: mp) {
    mp[size*2] += cnt/2;
    ans += cnt % 2;
  }
  cout << ans << endl;
  return 0;
}

E - Playlist

DP で解いた。

  • dp[i][j] = 時刻 i のときに j:0(1番目), j:1(1番目以外) の曲が流れているときの確率
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define endl '\n'
using mint = modint998244353;

int main() {
  int n,x; cin >> n >> x;
  vector<int> t(n);
  REP(i,n) cin >> t[i];

  // dp[i][j] := 時刻 i のときに j:0(1番目), j:1(1番目以外) になる確率
  vector dp(x+2,vector<mint>(2));
  mint r = (mint)1/n;
  REP(i,n) dp[min(x+1,t[i])][i == 0 ? 0 : 1] += r;

  REP(i,x+1) REP(j,n) REP(k,2) {
    if (dp[i][k] == 0) continue;
    dp[min(x+1,i + t[j])][j == 0 ? 0 : 1] += dp[i][k]*r;
  }

  cout << dp[x+1][0].val() << endl;
  return 0;
}

雑感

C で凡ミスして2WA、E は方針はすぐたったが、確率計算がうまくあわなくてかなりロスした。 確率や期待値問題、どうしても苦手意識がある

tic40さんのユニークビジョンプログラミングコンテスト2023 秋 (AtCoder Beginner Contest 323)での成績:1824位
パフォーマンス:1266相当
レーティング:1133→1147 (+14) :)
#AtCoder #ユニークビジョンプログラミングコンテスト2023秋(ABC323) https://atcoder.jp/users/tic40/history/share/abc323?lang=ja