オンサイト参加資格が無いので,オープンに出ました.
http://code-thanks-festival-2015-open.contest.atcoder.jp/
A AからBに行くときの最短はabs(A - B)です. この場合,100から-100に飛ぶなどということが出来ないので,この計算で大丈夫です.
1 2 3 4 5 int main () { int A, B; cin >>A >>B; cout <<(abs (A) + abs (A - B) + abs (B)) <<endl; return 0 ; }
B 全ての可能性を試します. 同じ数字を2回以上出力しないように注意して下さい.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 typedef pair<int , int > P;const int L = 2 ;int main () { int A[L], B[L], C; REP(i, L) cin >>A[i]; REP(i, L) cin >>B[i]; cin >>C; set <P> S; set <int > ans; REP(i, L){ REP(j, L){ P p = P(min(A[i], B[j]), max(A[i], B[j])); if (S.find(p) != S.end()) continue ; S.insert(p); if (p.first == C) ans.insert(p.second); if (p.second == C) ans.insert(p.first); } } cout <<ans.size() <<endl; for (int n : ans) cout <<n <<endl; return 0 ; }
C 生徒の数が少ないので,端から順に探していっても間に合います.
1 2 3 4 5 6 7 8 9 10 11 12 13 int solve (vector <int > &H, int X) { REP(i, H.size()) if (H[i] > X) return i + 1 ; return H.size() + 1 ; } int main () { int N, X; cin >>N; vector <int > H(N); REP(i, N) cin >>H[i]; cin >>X; cout <<solve(H, X) <<endl; return 0 ; }
D 既に今までのa = 0のクエリで得点を把握していれば,それを出力します. そうでなければ
p : (合計点 - 今分かっている得点)
n : まだその人が得点を把握していない人の数
を使って,以下のように計算します.
max(0, p - ((n - 1) * 100))
得点の範囲を知りたい人c以外のn - 1人全てが100点だった場合の点を考えます. 0未満になってしまう場合はcが0点である可能性があるので,0とします.
pが100以上なら100,そうでなければp
n人全てが0点だった場合の点を考えます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 int N, sum = 0 ;vector <int > S;vector < vector <bool > > v;void solve (int &b, int &c) { int k = 0 , cnt = 0 ; REP(i, N) if (v[b][i]) { k += S[i]; ++cnt; } int l = max(0 , sum - k - (N - cnt - 1 ) * 100 ), h = (sum - k >= 100 ? 100 : sum - k); cout <<l <<" " <<h <<endl; } int main () { cin >>N; S = vector <int >(N); REP(i, N) { cin >>S[i]; sum += S[i]; } v = vector < vector <bool > >(N, vector <bool >(N, 0 )); REP(i, N) v[i][i] = 1 ; int M; cin >>M; int a, b, c; REP(i, M){ cin >>a >>b >>c; --b; --c; if (a){ if (v[b][c]) cout <<S[c] <<" " <<S[c] <<endl; else solve(b, c); } else v[b][c] = 1 ; } return 0 ; }
E Sの中の,Tに含まれていない文字を全て消します. 消した結果の文字列S’の部分文字列にTがあればYES,そうでなければNOです.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const int ALPHA = 26 ;bool check (string a, string &b) { REP(i, (int )(a.length() - b.length()) + 1 ){ if (a.substr(i, b.length()) == b) return true ; } return false ; } bool solve (string &a, string &b) { stringstream ss; vector <bool > v(ALPHA, 0 ); for (char c : b) v[c - 'a' ] = 1 ; for (char c : a) if (v[c - 'a' ]) ss << c; return check(ss.str(), b); } int main () { int Q; cin >>Q; string S, T; REP(q, Q){ cin >>S >>T; cout <<(solve(S, T) ? "YES" : "NO" ) <<endl; } return 0 ; }
以下,本番中に解けず,解説を見て復習した問題です.
F 両者が最善を尽くした場合,1の実がとられないように,可能な限り1に隣接していない実を食べるはずなので,最終的には1と,1に隣接した実のみが残ります. この後,どちらが1の実を食べられるかどうかは,最初の実の数Nが偶数であるか奇数であるかで決定します.
1 2 3 4 5 6 7 8 9 10 11 12 13 int main () { int N, cnt = 0 ; cin >>N; REP(i, N - 1 ){ int a, b; cin >>a >>b; if (a == 1 || b == 1 ) ++cnt; } if (cnt == 1 ) cout <<"A" <<endl; else { if (N % 2 ) cout <<"B" <<endl; else cout <<"A" <<endl; } return 0 ; }
G 色の種類が
ci(1≦ci≦1,000,000,000)
と書いていて一瞬怯みますが,道の本数が
M(1≦M≦80,000)
なので,色の種類は多くても80,000種類にしかならないことが分かります.
そのため,closedを map<P, Int>
とでもmapで管理します.
余談ですが,私は本番で map<P, Int>
ではなくnumber_to_color
, color_to_number
という対応表みたいなmapを作ってダイクストラを書きましたが これだとMLEで落ちてしまいました.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 typedef long long int Int;typedef pair<Int, Int> P;typedef pair<P, Int> PP;const Int INF = 1e18 ;Int N, M; vector < vector <PP> > v;class C{ public : Int now, cost, color; C(Int nn, Int tt, Int cc){ now = nn; cost = tt; color = cc; } bool operator > (const C &c) const { return cost > c.cost; } }; Int solve () { priority_queue<C, vector <C>, greater<C> > open; open.push(C(0 , 0 , 1 )); map <P, Int> closed; while (!open.empty()){ C c = open.top(); open.pop(); if (c.cost > closed[P(c.now, c.color)]) continue ; if (c.now == N - 1 ) return c.cost; REP(i, v[c.now].size()){ Int to = v[c.now][i].first.first, color = v[c.now][i].first.second; Int cost = v[c.now][i].second; Int nextcost = c.cost + abs (c.color - color) + cost; if (closed.find(P(to, color)) == closed.end() || nextcost < closed[P(to, color)]){ closed[P(to, color)] = nextcost; open.push(C(to, nextcost, color)); } } } return INF; } int main () { cin >>N >>M; v = vector < vector <PP> >(N); REP(i, M){ Int a, b, c, t; cin >>a >>b >>c >>t; --a; --b; v[a].push_back(PP(P(b, c), t)); v[b].push_back(PP(P(a, c), t)); } cout <<solve() <<endl; return 0 ; }
H http://kmjp.hatenablog.jp/entry/2015/12/05/1100
ここが大変参考になります. (しゃくとり法ができなさすぎて,ほぼ参考元そのまま)
累積和は自作ライブラリから.
long long intを使わないとWAになることに注意.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 typedef long long int Int; typedef pair<Int, Int > P; typedef pair<P, P > PP; const Int MAX_H = 400; const Int MAX_W = 400; const Int N = 10; Int H, W, K, ans, v[N ][MAX_H ][MAX_W ], input[MAX_H ][MAX_W ]; void init(Int input[MAX_H ][MAX_W ]){ memcpy(v[0], input, sizeof(v[0])); FOR(num, 1, N) REP(i, H) REP(j, W) v[num ][i ][j ] = input[i ][j ] == num; REP(num, N){ FOR(i, 1, H) v[num][i][0] += v[num][i - 1][0]; FOR(i, 1, W) v[num][0][i] += v[num][0][i - 1]; FOR(y, 1, H) FOR(x, 1, W) v[num][y][x] += v[num][y - 1][x] + v[num][y][x - 1] - v[num][y - 1][x - 1]; } } Int calc(Int num, P a, P b){ Int ret = v[num ][b.Y ][b.X ]; if(a.X - 1 >= 0) ret -= v[num ][b.Y ][a.X - 1 ]; if(a.Y - 1 >= 0) ret -= v[num ][a.Y - 1 ][b.X ]; if(a.X - 1 >= 0 && a.Y - 1 >= 0) ret += v[num ][a.Y - 1 ][a.X - 1 ]; return ret; } Int solve(){ Int res = 0; REP(y1, H - 2){ REP(x1, W - 2){ Int n = y1 + 2; for(Int x2 = W - 1; x2 >= x1 + 2; --x2){ while(n < H && calc(0, P(y1, x1), P(n, x2)) <= K) ++n; FOR(y2, n, H){ Int num = calc(0, P(y1, x1), P(y2, x2)); if(num - K > 9) break; res += calc(num - K, P(y1 + 1, x1 + 1), P(y2 - 1, x2 - 1)); } } } } return res; } int main() { cin >>H >>W >>K; REP(i, H){ REP(j, W){ char c; cin >>c; input[i][j] = c - '0'; } } init(input); cout <<solve () <<endl ; return 0 ; }