ABC173に参加しました
AtCoderのコンテストに参加した際の結果と考え方、反省点などを書いていきます。
コンテストページはこちら
解いた/挑んだ問題
A問題
問題の概要
N円の商品を買うとき、必要最小限の1000円札のみで支払う場合のおつりはいくらになりますか?
制約
- Nは整数
どのように考えたか
Nを1000で割ったあまりを求め、あまりがある場合1000から、Nを1000で割ったあまりを引いて出力
余りがないなら0を出力
結果
二回目でAC
・提出したコード
#include"bits/stdc++.h" #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define REP(i, n) for (int i = 1; i <= (int)(n); i++) #define all(v) v.begin(), v.end() using namespace std; using ll = long long; using pi = pair<int, int>; const ll INF = 1LL << 60; int main() { int n; cin >> n; if (n % 1000) { cout << 1000 - (n % 1000) << endl; } else cout << 0 << endl; }
焦ってしまい一回目でACすることができなかった
ACまでの時間
ACしたのはコンテスト開始から3分後です。
B問題
問題の概要
コンテストに参加してN回のジャッジ結果が"AC","WA","TLE","RE"のいずれかであった
各結果がそれぞれ何回ずつであったかを
[結果] × 回数 で一行ずつ出力せよ
制約
- "AC","WA","TLE","RE"のいずれか
どのように考えたか
for文の中でmapに結果をいれて、"AC","WA","TLE","RE"のキーで出現回数を出力
結果
一発AC
提出したコード
#include"bits/stdc++.h" #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define REP(i, n) for (int i = 1; i <= (int)(n); i++) #define all(v) v.begin(), v.end() using namespace std; using ll = long long; using pi = pair<int, int>; const ll INF = 1LL << 60; int main() { int n; string a; map<string, int>mp; cin >> n; rep(i, n) { cin >> a; mp[a]++; } cout << "AC x " << mp["AC"] << endl; cout << "WA x " << mp["WA"] << endl; cout << "TLE x " << mp["TLE"] << endl; cout << "RE x " << mp["RE"] << endl; }
mapに入れてしまえば簡単だった
ACまでの時間
ACしたのはコンテスト開始から6分後です。
C問題
問題の概要
H行W列からなる白と黒で塗られているマス目が与えられる
そのうち、好きな行と好きな列を選んで赤く塗りつぶす
塗りつぶした後、残っている黒のマスがKと等しくなるような行列の選び方は何通りあるか
制約
- は'.'または'#'
どのように考えたか
二重bit全探索をして、残った黒のマスがKと等しいかをカウントしていく
結果
一発AC
・提出したコード
#include"bits/stdc++.h" #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define REP(i, n) for (int i = 1; i <= (int)(n); i++) #define all(v) v.begin(), v.end() using namespace std; using ll = long long; using pi = pair<int, int>; const ll INF = 1LL << 60; int main() { int h, w,key,black=0,cnt=0,tmp=0; string s; vector<string>grid; cin >> h >> w >> key; vector<int>bh(w, 0); vector<int>bw(h, 0); vector<int>hmemo,wmemo; vector<vector<int>>diffh(w,vector<int>(h,0)); rep(i, h) { cin >> s; grid.push_back(s); for (auto c : s) { if (c == '#')black++; if (c == '#')bw[i]++; } } rep(i, w) { rep(j, h) { if (grid[j][i] == '#') { bh[i]++; diffh[i][j]++; } } } for (int i = 0; i < (1 << w); i++) { for (int k = 0; k < (1 << h); k++) { tmp = black; hmemo.clear(); wmemo.clear(); rep(j, w) { if (i & (1 << j)) { tmp -= bh[j]; hmemo.push_back(j); } } rep(l, h) { if (k & (1 << l)) { tmp -= bw[l]; wmemo.push_back(l); } } for (auto s : hmemo) { for (auto g : wmemo)tmp += diffh[s][g]; } if (tmp == key)cnt++; } } cout << cnt << endl; }
初めて二重bit全探索を実装したが、ひっかけがなく解けて良かった
ACまでの時間
ACしたのはコンテスト開始から61分後。
D問題
問題の概要
N人はそれぞれのフレンドリーさです
このN人を円形に並べる時、最初の一人目を除く人は並べられた時の両脇のフレンドリーさの小さい方の心地よさポイントを獲得します
N人を最適に並べた場合、心地よさポイントの合計はいくらになるでしょうか
制約
- 入力はすべて整数
どのように考えたか
フレンドリーさを降順にソートして、二人目が得る心地よさは配列の0番目
三,四人目は一人目と二人目の間に置くことで二人目の心地よさを得られる
五、六人目は一人目と三人目の間に置くことで三人目の心地よさを得られる
のように、一人目を除き、二人目からN-2人目の心地よさをそれぞれ2回ずつ得ることができる
結果
時間内に解ききることはできませんでした
ACまでの時間
-
結果
コンテスト結果
ABCの3完でした。
C問題でだいぶ詰まってしまい、解くことはできたがD問題に一歩及ばずといった結果になった
パフォーマンス、レーティング変動
今回のパフォーマンスは茶色の638、前回より300上がりました。
レーティングはそれに伴い+14の527となりました。
反省点
今回はABCの3完をすることができたが、これから伸びていくためにはD問題を安定して解けるようにしなければならないので、
日頃の精進を忘れないようにしたい