ABC181に参加しました
AtCoderのコンテストに参加した際の結果と考え方、反省点などを書いていきます。
コンテストページはこちら
解いた/挑んだ問題
A問題
問題の概要
一日毎に白と黒の服を着る高橋君は白い服を着たN日後は何色の服を着るか
黒の時は"Black"、白の時は"White"と出力せよ
制約
- Nは整数
どのように考えたか
Nが奇数の時は黒、偶数の時は白の服と置き換えた
結果
1発AC
・提出したコード
#include<bits/stdc++.h> #include<atcoder/all> #define rep(i, n) for (long long i = 0; i < (long long)(n); i++) #define REP(i, n) for (long long i = 1; i <= (long long)(n); i++) #define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r) #define afor(a,t) for(auto a:t) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } using namespace std; using namespace atcoder; using ll = long long; using pi = pair<int, int>; int main() { int n; cin >> n; if(n%2==1){ cout << "Black" <<endl; }else{ cout << "White" <<endl; } return 0; }
A問題らしい問題だった
ACまでの時間
ACしたのはコンテスト開始から1分後です。
B問題
問題の概要
N回以下の操作を行う
- 整数A,Bが与えられ、A以上B以下の数を列挙する
列挙したすべての数の合計を出力せよ
制約
- 入力はすべて整数
どのように考えたか
等差数列の和により、1からBまでの和を求め、
1からA-1の和を引いたものを変数に足していき
最後に出力
結果
1発AC
提出したコード
#include<bits/stdc++.h> #include<atcoder/all> #define rep(i, n) for (long long i = 0; i < (long long)(n); i++) #define REP(i, n) for (long long i = 1; i <= (long long)(n); i++) #define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r) #define afor(a,t) for(auto a:t) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } using namespace std; using namespace atcoder; using ll = long long; using pi = pair<int, int>; int main() { int n,a,b; ll ans=0,tmp=0; cin >> n; rep(i,n){ cin >> a >> b; tmp = b*(b+1LL)/2; if(a != 1)tmp -= (a-1LL)*(a)/2LL; ans += tmp; } cout << ans <<endl; return 0; }
等差数列の和の公式を覚えていてよかった
ACまでの時間
ACしたのはコンテスト開始から5分後です。
C問題
問題の概要
2次元平面上にN個の点があり、i番目の点はにあります
N個の点の中で異なる3つの点が同一直線上にあるものは存在するか
存在する場合"Yes"を、しない場合"No"を出力せよ
制約
- 入力はすべて整数
どのように考えたか
Nが100しかないので、全探索を行い3点の傾きを計算して一致しているか判定
結果
コンテスト中に通すことはできませんでした
・提出したコード
#include<bits/stdc++.h> #include<atcoder/all> #define rep(i, n) for (long long i = 0; i < (long long)(n); i++) #define REP(i, n) for (long long i = 1; i <= (long long)(n); i++) #define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r) #define afor(a,t) for(auto a:t) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } using namespace std; using namespace atcoder; using ll = long long; using pi = pair<int, int>; int main() { int n, x, y; double a, b, c; int ans = 0; cin >> n; vector<pi>v(n); rep(i, n) { cin >> x >> y; v[i] = pi(x, y); } rep(i, n - 2) { FOR(j, i + 1, n - 1, 1) { FOR(k, j + 1, n, 1) { a = (double)(v[j].second - v[i].second) / (double)(v[j].first - v[i].first); b = (double)(v[k].second - v[i].second) / (double)(v[k].first - v[i].first); // /c = (double)(v[k].second - v[j].second) / (double)(v[k].first - v[j].first); if ((a+0.5) == (b+0.5))ans = true; } } } //Yes/Noを返す if (ans) cout << "Yes" << endl; else cout << "No" << endl; return 0; }
最後に1WA出したのは誤差の影響らしいので、式変形で誤差が生まれないようにしたいです。
ACまでの時間
なし
D問題
問題の概要
1~9の数字のみからなる数字列Sが与えられる
この数字列を並び替えて8の倍数に出来るかどうか
出来る場合"Yes"を、できない場合"No"を出力せよ
制約
- Sの各文字は1~9のいずれか
どのように考えたか
googleで8の倍数 判定方法 で検索して3桁以上の場合が出てきたので、
3桁はそれに倣って実装
2桁以下は全列挙して判定しました
結果
1発AC
・提出したコード
#include<bits/stdc++.h> #include<atcoder/all> #define rep(i, n) for (long long i = 0; i < (long long)(n); i++) #define REP(i, n) for (long long i = 1; i <= (long long)(n); i++) #define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r) #define afor(a,t) for(auto a:t) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } using namespace std; using namespace atcoder; using ll = long long; using pi = pair<int, int>; int main() { bool ans = false; vector<map<char, int>>vm; map<char, int>m; string ts; FOR(i, 100, 1000, 1) { if (i % 2 != 0)continue; int tmp = i / 2; int t = tmp % 100; if (t % 4 != 0)continue; m.clear(); ts = to_string(i); afor(a, ts)m[a]++; vm.push_back(m); } string s; cin >> s; if (s.size() < 3) { vector<string>v; v = { "8","16","24","23","04","48","56","46","27","08","88","69" }; sort(all(s)); afor(a, v)if (s == a)ans = true; } else { map<int, int>ss; afor(a, s)ss[a]++; afor(b, vm) { afor(c, b) { if (c.second <= ss[c.first])ans = true; else { ans = false; break; } } if (ans) { break; } } } //Yes/Noを返す if (ans) cout << "Yes" << endl; else cout << "No" << endl; return 0; }
3桁以上の場合の8の倍数判定の実装がなかなか重くて辛かったけど本番中に通せてよかった
ACまでの時間
ACしたのはコンテスト開始から53分後です。
結果
コンテスト結果
ABDの3完でした。
Dは実装力(?)で解けましたが、Cの式変形ができなかったので、もっと精進していきたいです
パフォーマンス、レーティング変動
今回のパフォーマンスは697、前回より70近く下がってしまいました。
レーティングはそれに伴い+8の631となりました。
反省点
今回はCが見当がつかなかったので、素早くDに移りACできたのはよかったのですが、
その後Cにもどっても解くことができず悔しかったです。
最近式変形の問題に弱いと思っているのでそこを鍛えていきたいと思います。