AOJ 2005: Water Pipe Construction
そすうライブラリのverifyに使われていたので解いてみた。
問題
Water Pipe Construction | Aizu Online Judge
- 有向グラフと各辺のコストが与えられる。
- 頂点
s
から頂点g1
とg2
を結ぶコスト最小の道を作るときのコストを求めよ
解法
全点対間の最小コストを求めておいて、全ての頂点v
について「s
からv
の最小コスト」+「v
からg1
の最小コスト」+「v
からg2
の最小コスト」を調べて最小となるコストを返せばよい。
ダイクストラ
#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) typedef long long int ll; using namespace std; struct edge { int src, dst, cost; edge(int s, int t, int c): src(s), dst(t), cost(c) {} }; const int INF = 1e8; void dijkstra(const vector<vector<edge> > &G, vector<int> &d, const int s) { d.assign(d.size(), INF); d[s] = 0; typedef pair<int, int> P; priority_queue<P, vector<P>, greater<P> > que; que.push(P(0, s)); while(!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if(d[v] < p.first) continue; for(auto &e : G[v]) { if(d[e.dst] > d[v] + e.cost) { d[e.dst] = d[v] + e.cost; que.push(P(d[e.dst], e.dst)); } } } } int main(void) { int n, m, s, g1, g2; while(cin >> n >> m >> s >> g1 >> g2 && n) { vector<vector<edge> > G(n); vector<vector<int> > d(n, vector<int>(n)); --s; --g1; --g2; REP(i, m) { int b1, b2, c; cin >> b1 >> b2 >> c; G[b1-1].push_back(edge(b1-1, b2-1, c)); } REP(i, n) { dijkstra(G, d[i], i); } int cost = numeric_limits<int>::max(); REP(i, n) { cost = min(cost, d[s][i] + d[i][g1] + d[i][g2]); } cout << cost << endl; } }
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2098833
ベルマン・フォード
#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) typedef long long int ll; using namespace std; struct edge { int src, dst, cost; edge(int s, int t, int c): src(s), dst(t), cost(c) {} }; const int INF = 1e8; void bellman_ford(const vector<edge> &edges, vector<int> &d, const int s) { d.assign(d.size(), INF); d[s] = 0; for(auto &i : d) { for(auto &e : edges) { d[e.dst] = min(d[e.dst], d[e.src] + e.cost); } } } int main(void) { int n, m, s, g1, g2; while(cin >> n >> m >> s >> g1 >> g2 && n) { vector<edge> edges; vector<vector<int> > d(n, vector<int>(n)); --s; --g1; --g2; REP(i, m) { int b1, b2, c; cin >> b1 >> b2 >> c; edges.push_back(edge(b1-1, b2-1, c)); } REP(i, n) { bellman_ford(edges, d[i], i); } int cost = numeric_limits<int>::max(); REP(i, n) { cost = min(cost, d[s][i] + d[i][g1] + d[i][g2]); } cout << cost << endl; } }
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2098843
ベルマン・フォードは次のような実装でもよい。
void bellman_ford(const vector<edge> &edges, vector<int> &d, const int s) { d.assign(d.size(), INF); d[s] = 0; for(int i=0; i < edges.size(); ++i) { edge e = edges[i]; if (d[e.dst] > d[e.src] + e.cost) { d[e.dst] = d[e.src] + e.cost; i = -1; } } }
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2098773
ワーシャル・フロイド
#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) typedef long long int ll; using namespace std; struct edge { int src, dst, cost; edge(int s, int t, int c): src(s), dst(t), cost(c) {} }; const int INF = 1e8; void warshall_floyd(vector<vector<int> > &d, vector<edge> &edges) { for(size_t i=0; i<d.size(); ++i) { d[i].assign(d[i].size(), INF); d[i][i] = 0; } for(auto &e : edges) { d[e.src][e.dst] = e.cost; } const size_t n = d.size(); for(size_t j=0; j<n; ++j) { for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { d[i][k] = min(d[i][k], d[i][j] + d[j][k]); } } } } int main(void) { int n, m, s, g1, g2; while(cin >> n >> m >> s >> g1 >> g2 && n) { vector<edge> edges; vector<vector<int> > d(n, vector<int>(n, INF)); --s; --g1; --g2; REP(i, m) { int b1, b2, c; cin >> b1 >> b2 >> c; edges.push_back(edge(b1-1, b2-1, c)); } warshall_floyd(d, edges); int cost = numeric_limits<int>::max(); REP(i, n) { cost = min(cost, d[s][i] + d[i][g1] + d[i][g2]); } cout << cost << endl; } }
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2098872
追記: 添字の順番を間違えたワーシャル・フロイド
KIJ (正しい)
for(size_t k=0; k<n; ++k) { for(size_t i=0; i<n; ++i) { for(size_t j=0; j<n; ++j) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455812
KJI (KIJと同じはず)
for(size_t k=0; k<n; ++k) { for(size_t j=0; j<n; ++j) { for(size_t i=0; i<n; ++i) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455808
IJK
for(size_t i=0; i<n; ++i) { for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
WA: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455813
IJK x 3
for(size_t i=0; i<n; ++i) { for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t i=0; i<n; ++i) { for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t i=0; i<n; ++i) { for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455814
IKJ x 3
for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { for(size_t j=0; j<n; ++j) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { for(size_t j=0; j<n; ++j) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { for(size_t j=0; j<n; ++j) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455815
JIK x 3
for(size_t j=0; j<n; ++j) { for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t j=0; j<n; ++j) { for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t j=0; j<n; ++j) { for(size_t i=0; i<n; ++i) { for(size_t k=0; k<n; ++k) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455817
JKI x 3
for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { for(size_t i=0; i<n; ++i) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { for(size_t i=0; i<n; ++i) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } for(size_t j=0; j<n; ++j) { for(size_t k=0; k<n; ++k) { for(size_t i=0; i<n; ++i) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
AC: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3455819
AOJ 1608: Selection of Participants of an Experiment
問題
Selection of Participants of an Experiment | Aizu Online Judge
- 数列の中で最も差の小さい2つの数の差を出力する
コード
#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) typedef long long int ll; using namespace std; int main(void) { int n; vector<int> a; while(cin >> n && n) { a.resize(n); REP(i, n) cin >> a[i]; int ans = numeric_limits<int>::max(); sort(a.begin(), a.end()); REP(i, n-1) ans = min(ans, a[i+1]-a[i]); cout << ans << endl; } }
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2094065
CODE FESTIVAL 2016 Final
A問題
A: Where's Snuke? - CODE FESTIVAL 2016 Final | AtCoder
snuke
という文字列がある場所の列(アルファベット)と行(数字)を出力
コード
#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) typedef long long int ll; using namespace std; string s; int H, W; int main(void) { cin >> H >> W; REP(i, H) { REP(j, W) { cin >> s; if(s=="snuke") { char c = 'A'+j; cout << c << i+1 << endl; } } } }
Submission #991415 - CODE FESTIVAL 2016 Final | AtCoder
B問題
B: Exactly N points - CODE FESTIVAL 2016 Final | AtCoder
- 和が
N
になる重複のない自然数の集合で最大の数字が最も小さい集合を出力せよ
方針
m(m+1)/2 > N
となる最小のm
を取り、大きいものから順に除外できる数字を除外していって、ちょうどN
になる集合を作る
コード
#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) typedef long long int ll; using namespace std; int main(void) { int N; cin >> N; int m = 1; for(int i=1; i<=N; ++i) { if(i*(i+1)/2 >= N) { m = i; break; } } int res = m*(m+1)/2 - N; vector<int> contain(m+1); contain.assign(contain.size(), 1); for(int i=m; i>0; --i) { if(res == 0) break; if(res-i >= 0) { res -= i; contain[i] = 0; } } for(int i=1; i<=m; ++i) { if(contain[i]) cout << i << endl; } }
Submission #992560 - CODE FESTIVAL 2016 Final | AtCoder
C問題
C: Interpretation - CODE FESTIVAL 2016 Final | AtCoder
N
人が話すM
種類の言語が与えられる。全員が意思疎通可能か答えろ
方針
N+M
個の頂点を持つ二部グラフを作って人を表すN
個の頂点が連結かどうか調べる- 連結判定はDFSでできる
コード
#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) typedef long long int ll; using namespace std; vector<vector<int> > edge; vector<bool> visit; void dfs(int v) { if(visit[v]) return; visit[v] = true; for(int i=0; i<edge[v].size(); ++i) { dfs(edge[v][i]); } } int main(void) { int N, M; int K, L; cin >> N >> M; edge.resize(N+M); REP(i, N) { cin >> K; edge[i].resize(K); REP(j, K) { cin >> L; L = N+L-1; edge[i][j] = L; edge[L].push_back(i); } } visit.resize(N+M); dfs(0); REP(i, N) { if(!visit[i]) { cout << "NO" << endl; return 0; } } cout << "YES" << endl; }
Submission #993138 - CODE FESTIVAL 2016 Final | AtCoder
D問題
通らず
E問題
部分点を狙ってt
秒でできる最大クッキー数を考えたが失敗
AOJ 1600: Entrance Examination
問題
Entrance Examination | Aizu Online Judge
codefestival前の肩ならし
#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) typedef long long int ll; using namespace std; int main(void) { int m, nmin, nmax; while(cin >> m >> nmin >> nmax && m) { vector<int> p(m); REP(i, m) scanf("%d", &p[i]); sort(p.begin(), p.end(), greater<int>()); int gap = 0; int ans = 0; for(int i=nmin-1; i<nmax; ++i) { if(p[i]-p[i+1] >= gap) { gap = p[i]-p[i+1]; ans = i+1; } } printf("%d\n", ans); } }
CODE FESTIVAL 2016 qual C
A問題
A: CF - CODE FESTIVAL 2016 qual C | AtCoder
文字列がCF
を部分文字列として含むか判定せよ
方針
C
を見つけたらレベルへ、レベル1でF
を見つけたらクリアみたいなコード
#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) typedef long long int ll; using namespace std; int main(void) { string s; int k=0; cin >> s; for(int i=0; i<s.size(); ++i) { if(k==0 && s[i]=='C') k=1; if(k==1 && s[i]=='F') {k=2; break;} } if(k==2) cout << "Yes" << endl; else cout << "No" << endl; }
Submission #942379 - CODE FESTIVAL 2016 qual C | AtCoder
B問題
B: K個のケーキ / K Cakes - CODE FESTIVAL 2016 qual C | AtCoder
なるべく連続したケーキを食べないようにするとき、連続したケーキを食べる回数
方針
可能なら前回食べたケーキを食べないようにして、残りが一番多いケーキを食べる
コード
#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) typedef long long int ll; using namespace std; int main(void) { int K, T; int a[101]; cin >> K >> T; REP(i, T) { cin >> a[i]; } int ans = 0; int max = 0, max_index=-1; REP(j, T) if(a[j] > max) {max = a[j]; max_index = j;} int before = max_index; a[max_index]--; REP(i, K-1) { max = 0, max_index=-1; REP(j, T) if(a[j] > max && j!=before) {max = a[j]; max_index = j;} if(max_index != -1) { before = max_index; a[max_index]--; } else { a[before]--; ans++; } } cout << ans << endl; }
Submission #943260 - CODE FESTIVAL 2016 qual C | AtCoder
C問題
C: 二人のアルピニスト / Two Alpinists - CODE FESTIVAL 2016 qual C | AtCoder
- 右から見てそこまでで一番高い山と左から見たそこまでで一番高い山の標高が与えられる
- 情報に矛盾があれば0、なければありえる山の高さの場合の数を出力
方針
- 各山についてあり得る標高の種類を記録しておいて後で掛ける
i
番目のデータで最高標高が更新されていたら1通りに確定- 確定しない場合はその時点での標高通りの組み合わせがある。右からと左からで低い方
- 左から確定した山の高さを使って、右から見たときの最高標高が確定値よりも低かったら矛盾
コード
#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) typedef long long int ll; using namespace std; ll T[100001], A[100001]; ll cand[100001], kaku[100001]; ll mod = 1000000007; int main(void) { int N; bool flag = true; cin >> N; REP(i, N) cin >> T[i]; REP(i, N) cin >> A[i]; if(T[N-1] != A[0]) { cout << 0 << endl; return 0; } cand[0] = 1; FOR(i, 1, N) { if(T[i] > T[i-1]) { cand[i] = 1; kaku[i] = T[i]; } else { cand[i] = T[i]; kaku[i] = -1; } } cand[N-1] = 1; for(int i=N-2; i>=0; --i) { if(kaku[i] != -1 && A[i] < kaku[i]) { flag = false; break; } if(A[i] > A[i+1]) cand[i] = 1; else cand[i] = min(cand[i], A[i]); } if(flag == false) { cout << 0 << endl; return 0; } ll ans = 1; REP(i, N) { ans = (ans*cand[i])%mod; } cout << ans << endl; }
Submission #944505 - CODE FESTIVAL 2016 qual C | AtCoder
D, E
解けない
CODE FESTIVAL 2016 qual A
来世に期待
A
A: CODEFESTIVAL 2016 - CODE FESTIVAL 2016 qual A | AtCoder
- 長さ12の文字列sの前半4文字と後半8文字の間に半角スペースを1つ挿入して出力せよ
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int main(void) { string s; cin >> s; cout << s.substr(0, 4) << " " << s.substr(4,11) << endl; }
Submission #890791 - CODE FESTIVAL 2016 qual A | AtCoder
std::string::substr()
の関数名を正確に覚えていなかったから検索してた。
B
B: 仲良しうさぎ / Friendly Rabbits - CODE FESTIVAL 2016 qual A | AtCoder
N
行の入力でうさぎi
がうさぎj
を好きという情報が与えられる。(i != j
)- うさぎ
i
がうさぎj
を好き かつ うさぎj
がうさぎi
を好きというペアの数を求めよ
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int R[100001]; int main(void) { int N, a; cin >> N; rep(i, N) { cin >> a; R[i] = a-1; } int ans = 0; rep(i, N) { if(R[R[i]] == i) ans++; } cout << ans/2 << endl; }
Submission #892907 - CODE FESTIVAL 2016 qual A | AtCoder
- 0-indexedにするために入力から1引く処理を入れた
- 配列サイズを間違えていて1WA
C
C: 次のアルファベット / Next Letter - CODE FESTIVAL 2016 qual A | AtCoder
- 文字列から1文字選んで次の文字(z
の次はa
)にする操作をK回まで行える。辞書順最小の文字列を作れ
さすがに余裕だと思っていたら、ここでハマって終了。
ACするコード (ジャッジ結果)
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int main(void) { string s; int K, n; cin >> s >> K; n = s.size()-1; rep(i, n) { int p = 'z'-s[i]+1; if(s[i] != 'a' && K >= p) { K -= p; s[i] = 'a'; } } s[n] = 'a' + (s[n]-'a'+K)%26; cout << s << endl; }
ACしないコード (ジャッジ結果)
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int main(void) { string s; int K, n; cin >> s >> K; n = s.size()-1; rep(i, n) { int p = 'z'-s[i]+1; if(s[i] != 'a' && K >= p) { K -= p; s[i] = 'a'; } } s[n] += K%26; if(s[n] > 'z') s[n] = 'a' + (s[n]-'z'-1); cout << s << endl; }
一度z
より大きい値を入れてから戻すという処理を書いたら、char型に入れられる値の範囲が-128から127(一般的な環境の話)なせいでif文が成立せず通らなくなっていたようだ。
ダメになる例
今までASCIIコードを操作する問題では数字(ASCIIコードで48〜57)しか扱ったことがなかったのでこういうハマり方をしたことがなかった。
以後気をつけよう。
D
D: マス目と整数 / Grid and Integers - CODE FESTIVAL 2016 qual A | AtCoder
- 任意の2x2の正方形が
左上+右下=右上+左下
を満たすようにRxC
のマス目に非負整数を書き込むことができるか
editorialにある通り実装したのに1時間かかった
#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) typedef long long int ll; using namespace std; int R, C, N; vector<ll> w; struct E{ int to, cost; E(int t, int c): to(t), cost(c) {}; }; vector<vector<E> > edge; ll rmin, cmin; bool dfs(int v) { if(v < R) rmin = min(rmin, w[v]); else cmin = min(cmin, w[v]); REP(i, edge[v].size()) { E e = edge[v][i]; if(w[e.to] != -1) { if(w[v]+w[e.to]!=e.cost) return false; } else { w[e.to] = e.cost - w[v]; if(!dfs(e.to)) return false; } } return true; } int main(void) { int tr, tc, ta; cin >> R >> C >> N; edge.resize(R+C); REP(i, N) { cin >> tr >> tc >> ta; tr--; tc--; edge[tr].push_back(E(R+tc, ta)); edge[R+tc].push_back(E(tr, ta)); } w.resize(R+C); w.assign(R+C, -1); REP(i, R+C) { if(w[i] != -1 || edge[i].size() == 0) continue; w[i] = 0; rmin = numeric_limits<ll>::max(); cmin = numeric_limits<ll>::max(); if(!dfs(i) || rmin+cmin < 0) { cout << "No" << endl; return 0; } } cout << "Yes" << endl; }
Submission #899631 - CODE FESTIVAL 2016 qual A | AtCoder
- 解説中の「上側にR個の頂点を並べ,下側にC個の頂点を並べ」たグラフを、前の
R
個が上側・後ろのC
個が下側となる全体でR+C
個の頂点を持つグラフとして表現し、dfsで条件判定した rmin
とcmin
で非負になることを確認した- 重みは
long long int
でないとオーバーフローしてWA(それでハマってた)。
E
そのうち……
Codeforces Round #372 (Div. 2)
2回目のCodeforces。
A問題
http://codeforces.com/contest/716/problem/A
入力の間隔がcを超えたらリセット、そうでなければインクリメントという感じで数えていく
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int main(void) { int n, c, ans, t, before; cin >> n >> c; ans = 0; before = 0; rep(i, n) { cin >> t; if(t - before > c) ans = 1; else ans++; before = t; } cout << ans << endl; }
B問題
http://codeforces.com/contest/716/problem/B
入力文字列の長さ26の部分列がA〜Zを重複なく含むようにする。
長さ26の部分列を全て見て、2回以上出現するアルファベットがなければいい感じに埋めてつくれる。
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for(int i=0; i<(int)(n); ++i) int main(void) { string S; cin >> S; bool none = true; if(S.size() < 26) { cout << -1 << endl; return 0; } char list[26]; rep(i, S.size()-25) { rep(j, 26) list[j] = 0; for(int j=i; j<i+26; ++j) { list[S[j]-'A']++; } bool flag = true; rep(j, 26) { if(list[j] > 1) flag = false; } if(flag) { int k = 0; for(int j=0; j<S.size(); ++j) { if(j >= i && j<i+26) { if(S[j] == '?') { for(; k<26; ++k) { if(list[k] == 0) { char c = 'A'+k; cout << c; list[k] = 1; break; } } } else { cout << S[j]; } } else { if(S[j] == '?') { cout << 'A'; } else { cout << S[j]; } } } cout << endl; none = false; break; } } if(none) cout << -1 << endl; }
C問題
http://codeforces.com/contest/716/problem/C
変なルールに従ってレベルアップするために何回ボタンを押せばいいか。
今のレベルと次のレベルの公倍数の平方になるまでボタンを押せばレベルアップできるので、各レベルの回数はO(1)で求まる。 全部用意しておいて入力に従って表示するだけ。
#include <bits/stdc++.h> using namespace std; typedef long long int ll; #define rep(i, n) for(int i=0; i<(int)(n); ++i) ll dp[100001]; int main(void) { dp[1] = 2; for(ll k=2; k<=100000; ++k) { dp[k] = (k+1)*(k+1)*k - (k-1); } int n; cin >> n; for(int i=1; i<=n; ++i) { cout << dp[i] << endl; } }
D問題, E問題
Dは?を1としてdijkstraで最短路を求めてから、最短路がLになるよう増やせばいいのかなと思っていろいろ試したがそれが最短路ではなくなってしまう場合を考慮してなくて時間内に解けず。 Eは開いてすらいない。
まだsystem test通っていないのでACかは不明。