ABC 119
A
- 2019年より後か、2019年かつ5月以降なら
Heisei
を出力し、それ以外ならTBD
を出力する
#include <bits/stdc++.h> #define REP(i, n) for (int i = 0; i < (int)(n); ++i) #define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i) using ll = long long int; using namespace std; int main() { string S; cin >> S; stringstream ss(S); int y, m, d; char c; ss >> y >> c >> m >> c >> d; if (y > 2019 || (y == 2019 && m >= 5)) cout << "TBD" << endl; else cout << "Heisei" << endl; }
Submission #5195221 - AtCoder Beginner Contest 119
B
JPY
ならそのまま、BTC
なら日本円に換算してから総和を取る
#include <bits/stdc++.h> #define REP(i, n) for (int i = 0; i < (int)(n); ++i) #define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i) using ll = long long int; using namespace std; int main() { int N; cin >> N; double ans = 0.0; REP(i, N) { double x; string u; cin >> x >> u; if (u == "JPY") ans += x; else ans += x * 380000.0; } cout << ans << endl; }
Submission #5196369 - AtCoder Beginner Contest 119
C
- 自力では解法が思いつかなかった
- 合成魔法の使い方を全探索すればよい
- 長さ0の竹を3本用意しておき、合成魔法を3本の竹のどれかに対して使うと考えると書きやすい
- 初回の合成魔法をコスト0とすれば同じ結果になる(
dfs
関数内で返り値を-30
しているのはこの処理) - 3本の初期竹に対して、少なくとも1回は合成魔法を使う必要があることに注意
- 初回の合成魔法をコスト0とすれば同じ結果になる(
#include <bits/stdc++.h> #define REP(i, n) for (int i = 0; i < (int)(n); ++i) #define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i) using ll = long long int; using namespace std; vector<int> l; int N, A, B, C; int dfs(int mp, int a, int b, int c, int n) { int tmp = numeric_limits<int>::max() >> 1; if (n == (int)l.size()) { if ((a == 0) || (b == 0) || (c == 0)) { return tmp; } else { return mp + abs(A - a) + abs(B - b) + abs(C - c) - 30; } } tmp = min(tmp, dfs(mp + 10, a + l[n], b, c, n + 1)); tmp = min(tmp, dfs(mp + 10, a, b + l[n], c, n + 1)); tmp = min(tmp, dfs(mp + 10, a, b, c + l[n], n + 1)); tmp = min(tmp, dfs(mp, a, b, c, n + 1)); return tmp; } int main() { cin >> N >> A >> B >> C; l.resize(N); REP(i, N) cin >> l[i]; cout << dfs(0, 0, 0, 0, 0) << endl; }
Submission #5220254 - AtCoder Beginner Contest 119
D
s
とt
をソートしておくx[i]
よりも左にある神社・寺のうち最も右にあるものの添字(l
,l2
とした)を二分探索で求める- めぐる式二分探索で書いたけど
std::upper_bound
使えば十分だった
- めぐる式二分探索で書いたけど
- 最小の移動距離は次のうちのどれか
- 左側にある神社・寺のうち遠い方までの距離 (
max(x[i] - t[l2], x[i] - s[l])
) - 左側の神社に行ってから右側の寺に行くまでの距離 (
(x[i] - s[l]) + (t[l2 + 1] - s[l])
) - 左側の寺に行ってから右側の神社に行くまでの距離 (
(x[i] - t[l2]) + (s[l + 1] - t[l2])
) - 右側の神社に行ってから左側の寺に行くまでの距離 (
(s[l + 1] - x[i]) + (s[l + 1] - t[l2])
) - 右側の寺に行ってから左側の神社に行くまでの距離 (
(t[l2 + 1] - x[i]) + (t[l2 + 1] - s[l])
) - 右側にある神社・寺のうち遠い方までの距離 (
max(s[l + 1] - x[i], t[l2 + 1] - x[i])
)
- 左側にある神社・寺のうち遠い方までの距離 (
s
とt
の左端と右端に遠い距離の神社・寺をいれておくと端の処理が楽
#include <bits/stdc++.h> #define REP(i, n) for (int i = 0; i < (int)(n); ++i) #define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i) using ll = long long int; using namespace std; int main() { ll A, B, Q; cin >> A >> B >> Q; vector<ll> s(A + 2), t(B + 2), x(Q); s[0] = -1e12; s[A + 1] = 1e12; t[0] = -1e12; t[B + 1] = 1e12; REP(i, A) cin >> s[i + 1]; REP(i, B) cin >> t[i + 1]; REP(i, Q) cin >> x[i]; sort(s.begin(), s.end()); sort(t.begin(), t.end()); REP(i, Q) { int l = 0, r = A + 2; while (r - l > 1) { int mid = (l + r) / 2; if (s[mid] <= x[i]) l = mid; else r = mid; } int l2 = 0, r2 = B + 2; while (r2 - l2 > 1) { int mid = (l2 + r2) / 2; if (t[mid] <= x[i]) l2 = mid; else r2 = mid; } cout << min({max(x[i] - t[l2], x[i] - s[l]), (x[i] - s[l]) + (t[l2 + 1] - s[l]), (x[i] - t[l2]) + (s[l + 1] - t[l2]), (s[l + 1] - x[i]) + (s[l + 1] - t[l2]), (t[l2 + 1] - x[i]) + (t[l2 + 1] - s[l]), max(s[l + 1] - x[i], t[l2 + 1] - x[i])}) << endl; } }