AtCoder Beginner Contest 112に参加しました
AtCoder Beginner Contest 112に参加したので記録を残したいと思います.
問題のタイトルは以下のようになっています.
- A - Programming Education
- B - Time Limit Exceeded
- C - Pyramid
- D - Partition
A - Programming Education
問題の概要
入力がならば'Hello World'を出力し、ならば更に整数の入力を受け取り、の結果を出力する.
解法
のときとのときで条件分岐してあげます.
最初に整数を受け取るのではなく、のときにのみ入力を受け取るように気をつけます.
#include <iostream> #include <string> #include <vector> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <stack> #include <queue> #include <set> #include <cstring> using namespace std; // ascending order #define vsort(v) sort(v.begin(), v.end()) // descending order #define vsort_r(v) sort(v.begin(), v.end(), greater<int>()) #define vunique(v) unique(v.begin(), v.end()) #define mp make_pair #define ts(x) to_string(x) #define rep(i, a, b) for(int i = (int)a; i < (int)b; i++) #define repm(i, a, b) for(int i = (int)a; i > (int)b; i--) #define bit(a) bitset<8>(a) #define des_priority_queue priority_queue<int, vector<int>, greater<int> > #define all(v) (v).begin(), (v).end() typedef long long ll; typedef pair<int, int> P; const ll INF = 1e18; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N; cin >> N; if(N == 1) { cout << "Hello World" << endl; } else { int A, B; cin >> A >> B; cout << A + B << endl; } }
B - Time Limit Exceeded
問題の概要
個の経路のなかで、時間以内に帰宅できる経路のうちコストが最小となる経路のコストを出力する.
ただし、番目の経路はコストかけて時間で帰宅できる.
解法
全探索します. 時間以下のに対応するコストの中で最小のものを出力することで目的を果たせます.
#include <iostream> #include <string> #include <vector> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <stack> #include <queue> #include <set> #include <cstring> using namespace std; // ascending order #define vsort(v) sort(v.begin(), v.end()) // descending order #define vsort_r(v) sort(v.begin(), v.end(), greater<int>()) #define vunique(v) unique(v.begin(), v.end()) #define mp make_pair #define ts(x) to_string(x) #define rep(i, a, b) for(int i = (int)a; i < (int)b; i++) #define repm(i, a, b) for(int i = (int)a; i > (int)b; i--) #define bit(a) bitset<8>(a) #define des_priority_queue priority_queue<int, vector<int>, greater<int> > #define all(v) (v).begin(), (v).end() typedef long long ll; typedef pair<int, int> P; const ll INF = 1e18; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N, T; cin >> N >> T; vector<int> c, t; rep(i, 0, N) { int tmp_c, tmp_t; cin >> tmp_c >> tmp_t; c.push_back(tmp_c); t.push_back(tmp_t); } int rsl = 1e9; rep(i, 0, N) { if(t[i] <= T) rsl = min(rsl, c[i]); } if(rsl == 1e9) cout << "TLE" << endl; else cout << rsl << endl; }
C - Pyramid
問題の概要
ピラミッドには中心座標と高さが定まっている. 座標の高度はである.
の高度はであるという情報が個与えられるので、その情報をもとに中心座標と高さを求める.
解法
最初はなんのこっちゃ分からなかったのですが、入力例2のが0以上100以下の整数であるとわかっていることに注意せよ.という一文を見て閃きました.
とが100以下の整数ならそれらに対して全探索しちゃえば良いのでは?と考えました. (制約を見た時点で思いつくべきでしたが、なぜかこの一文を見た時に解法を思いつきました.)
そうすると、残るをどうするかが問題になってきます. 残るを定めてしまえば、適当に定めたを用いて個の情報に矛盾しないか一つずつ試していけば良いことになります.
の定め方はが0のときとそうでないときで場合分けしました.
が0でないとき
という定義より、ある中心座標の候補であるを用いて、が成り立ちます. したがって、となります.
これで、あるに対するを一つ定めることができました. このを用いたとき全ての情報に矛盾が生じなかったとき、そのが答えとなります.
が0のとき
が0のときは、となります. したがって、の値は、に絞ることができます. したがってこの範囲の中で情報に矛盾の生じないが存在すれば、そのが答えとなります.
#include <iostream> #include <string> #include <vector> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <stack> #include <queue> #include <set> #include <cstring> using namespace std; // ascending order #define vsort(v) sort(v.begin(), v.end()) // descending order #define vsort_r(v) sort(v.begin(), v.end(), greater<int>()) #define vunique(v) unique(v.begin(), v.end()) #define mp make_pair #define ts(x) to_string(x) #define rep(i, a, b) for(int i = (int)a; i < (int)b; i++) #define repm(i, a, b) for(int i = (int)a; i > (int)b; i--) #define bit(a) bitset<8>(a) #define des_priority_queue priority_queue<int, vector<int>, greater<int> > #define all(v) (v).begin(), (v).end() typedef long long ll; typedef pair<int, int> P; const ll INF = 1e18; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N; cin >> N; vector<int> x, y, h; rep(i, 0, N) { int tmp_x, tmp_y, tmp_h; cin >> tmp_x >> tmp_y >> tmp_h; x.push_back(tmp_x); y.push_back(tmp_y); h.push_back(tmp_h); } rep(xi, 0, 101) rep(yi, 0, 101) { if(h[0] != 0) { int H = h[0] + abs(x[0] - xi) + abs(y[0] - yi); bool flag = true; rep(i, 0, N) { if(h[i] != max(H - abs(x[i] - xi) - abs(y[i] - yi), 0)) { flag = false; break; } } if(flag) { cout << xi << " " << yi << " " << H << endl; return 0; } } else { int max_h = abs(x[0] - xi) + abs(y[0] - yi); rep(hi, 0, max_h + 1) { bool flag = true; rep(i, 0, N) { if(h[i] != max(hi - abs(x[i] - xi) - abs(y[i] - yi), 0)) { flag = false; break; } } if(flag) { cout << xi << " " << yi << " " << hi << endl; } } } } }
D - Partition
問題の概要
整数が与えられる.
となる整数からなる長さの数列において、の最大公約数の取り得る最大値を求める.
解法
整数問題苦手ですね... またしても時間内に解けませんでした.
例えば数列の最大公約数をとしたとき、はの倍数となります. したがって、それらの和であるもの倍数となります.
がの倍数、つまりはの約数であることに注意すると、の候補を全部列挙することができます. (約数を列挙するライブラリを持っていると便利です.)
であることに注意すると、となります.
を満たすを用いて、、とすることで、最大公約数がとなる数列を作ることができます.
したがって、の約数でありかつ、を満たすの中の最大値を結果として出力してあげれば良いことになります.
#include <iostream> #include <string> #include <vector> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <stack> #include <queue> #include <set> #include <cstring> using namespace std; // ascending order #define vsort(v) sort(v.begin(), v.end()) // descending order #define vsort_r(v) sort(v.begin(), v.end(), greater<int>()) #define vunique(v) unique(v.begin(), v.end()) #define mp make_pair #define ts(x) to_string(x) #define rep(i, a, b) for(int i = (int)a; i < (int)b; i++) #define repm(i, a, b) for(int i = (int)a; i > (int)b; i--) #define bit(a) bitset<8>(a) #define des_priority_queue priority_queue<int, vector<int>, greater<int> > #define all(v) (v).begin(), (v).end() typedef long long ll; typedef pair<int, int> P; const ll INF = 1e18; vector<ll> divisor(ll n) { vector<ll> res; for(int i = 1; i * i <= n; i++) { if(n % i == 0) { res.push_back(i); if(i != n / i) res.push_back(n / i); } } return res; } int main(){ cin.tie(0); ios::sync_with_stdio(false); ll N, M; cin >> N >> M; vector<ll> v = divisor(M); ll max_v = 1; rep(i, 0, v.size()) { if(v[i] * N <= M) max_v = max(max_v, v[i]); } cout << max_v << endl; }
感想
C問題に関しては制約を見逃すことが多く、4WA1ACという結果でした...
ここら辺の正確性をどうにかすればもう少し良いレートになれるかなと感じています.
また、整数問題もリアルタイムで解けることが少ないので、練習していく必要がありますね...