結果
| 問題 |
No.3301 Make Right Triangle
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-10-05 15:40:38 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,047 bytes |
| コンパイル時間 | 5,578 ms |
| コンパイル使用メモリ | 335,840 KB |
| 実行使用メモリ | 7,720 KB |
| 最終ジャッジ日時 | 2025-10-05 15:40:51 |
| 合計ジャッジ時間 | 9,440 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | WA * 1 TLE * 1 -- * 7 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
#define all(v) v.begin(), v.end()
#define SORT(v) sort(v.begin(), v.end())
#define RSORT(v) sort(v.rbegin(), v.rend())
#define REVERSE(v) reverse(v.begin(), v.end())
#define ll long
#define ld long double
#define int ll
// https://algo-method.com/descriptions/119#h2-61
vector<pair<long long, long long>> prime_factorize(long long N) {
// 答えを表す可変長配列
vector<pair<long long, long long>> res;
// √N まで試し割っていく
for (long long p = 2; p * p <= N; ++p) {
// N が p で割り切れないならばスキップ
if (N % p != 0) {
continue;
}
// N の素因数 p に対する指数を求める
int e = 0;
while (N % p == 0) {
// 指数を 1 増やす
++e;
// N を p で割る
N /= p;
}
// 答えに追加
res.emplace_back(p, e);
}
// 素数が最後に残ることがありうる
if (N != 1) {
res.emplace_back(N, 1);
}
return res;
}
// https://algo-method.com/descriptions/84#h2-44
// N の約数をすべて求める関数
vector<long long> calc_divisors(long long N) {
// 答えを表す集合
vector<long long> res;
// 各整数 i が N の約数かどうかを調べる
for (long long i = 1; i * i <= N; ++i) {
// i が N の約数でない場合はスキップ
if (N % i != 0) continue;
// i は約数である
res.push_back(i);
// N ÷ i も約数である (重複に注意)
if (N / i != i) res.push_back(N / i);
}
// 約数を小さい順に並び替えて出力
sort(res.begin(), res.end());
return res;
}
int pow2(int n) {
return n * n;
}
int32_t main() {
int t;
cin >> t;
while (t--) {
int L;
cin >> L;
if (L % 2 == 0) {
int tmp = L / 2;
auto factors = prime_factorize(tmp);
int m = factors[0].first * factors[0].second;
int n = tmp / m;
if (m * m - n * n < 0) {
swap(m, n);
}
cout << m * m - n * n << " " << 2 * m * n << " " << m * m + n * n << endl;
assert(pow2(m * m - n * n) + pow2(2 * m * n) == pow2(m * m + n * n));
} else {
// 斜めに配置したい
auto divs = calc_divisors(L);
for (int i = 0; i < divs.size(); i++) {
int p = divs[i];
int q = L / p;
if (p * p - q * q < 0) {
swap(p, q);
}
if ((pow2(p) + pow2(q)) % 2 == 0 && (pow2(p) - pow2(q)) % 2 == 0) {
cout << (p * p - q * q) / 2 << " " << p * q << " " << (p * p + q * q) / 2 << endl;
assert(pow2((p * p - q * q) / 2) + pow2(p * q) == pow2((p * p + q * q) / 2));
break;
}
}
}
}
}