【AtCoder】ABC 409 C - Equilateral Triangle | 緑コーダーが解くAtCoder
配点: 300 点 / 実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 421 / NoviSteps: 2Q
問題概要
円周が の円があり、この円周上に
個の点が配置されている。
に対し、点
は点
から時計回りに円周上を
進んだ位置にある。
整数の組 であって、以下の2つをともに満たすものの個数を求めよ。
- 3点
はすべて異なる位置にある。
- 3点
を頂点とする三角形は正三角形である。
制約
- 入力は全て整数
考察
大前提として、円周上の3点を選んで正三角形を作るためには を3等分する必要がある。つまり、
は
の倍数でなければならない。
その上で、点 を原点として円周上に座標軸を取り、その座標系での
個の点の座標
を以下のように累積和を利用して求める。
これらの座標の中から、座標が であるような3点を選ぶ
。
これら3点の関係は以下のようになる。
このとき、各座標ごとの点の度数分布表をmapで管理すれば(これを とする)、
を固定したときに作ることができる正三角形の個数は
と計算できる。したがって、 の位置を
から
まですべて試して、その総和を取ったものが答えとなる。
実装時はオーバーフローに注意(1敗)。
実装例
#include <bits/stdc++.h> #define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++) using namespace std; using ll = long long; // ======================================== // int main() { ll N, L; cin >> N >> L; vector<int> d(N - 1); rep(i, 0, N - 1) cin >> d[i]; if (L % 3 != 0) { cout << 0 << endl; return 0; } vector<ll> pos(N, 0); map<ll, ll> cnt; cnt[0]++; rep(i, 1, N) { pos[i] = (pos[i - 1] + d[i - 1]) % L; cnt[pos[i]]++; } ll ans = 0; ll distance = L / 3; rep(i, 0, distance) { ans += cnt[i] * cnt[i + distance] * cnt[i + 2 * distance]; } cout << ans << endl; return 0; }
実装時間: 30分
コメント
円環やら何やらを考え始めてタイムロスしてしまった。