結果
問題 | No.195 フィボナッチ数列の理解(2) |
ユーザー | r_dream0 |
提出日時 | 2017-02-08 23:31:14 |
言語 | C++11 (gcc 11.4.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,720 bytes |
コンパイル時間 | 758 ms |
コンパイル使用メモリ | 69,632 KB |
実行使用メモリ | 6,948 KB |
最終ジャッジ日時 | 2024-06-07 13:12:42 |
合計ジャッジ時間 | 1,744 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 1 ms
5,376 KB |
testcase_05 | WA | - |
testcase_06 | AC | 1 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | AC | 1 ms
5,376 KB |
testcase_13 | WA | - |
testcase_14 | AC | 2 ms
5,376 KB |
testcase_15 | WA | - |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | WA | - |
testcase_18 | AC | 1 ms
5,376 KB |
testcase_19 | AC | 2 ms
5,376 KB |
testcase_20 | AC | 1 ms
5,376 KB |
testcase_21 | WA | - |
testcase_22 | AC | 2 ms
5,376 KB |
testcase_23 | AC | 1 ms
5,376 KB |
testcase_24 | AC | 2 ms
5,376 KB |
ソースコード
#include <iostream> #include <algorithm> #include <limits> #include <cstdint> #include <vector> using namespace std; int64_t extgcd(int64_t a, int64_t b, int64_t &x, int64_t &y) { for (int64_t u = y = 1, v = x = 0; a; ) { int64_t q = b / a; swap(x -= q * u, u); swap(y -= q * v, v); swap(b -= q * a, a); } return b; } vector<int64_t> fib; // ひとつの場合はextgcdより良い感じになるものを探す void solve_single(int64_t X) { int64_t A = numeric_limits<int64_t>::max(); int64_t B = numeric_limits<int64_t>::max(); for(size_t i = 0; i < fib.size() - 1; i++) { int64_t x, y, kmax, kmin; extgcd(fib[i], fib[i + 1], x, y); // fib[i]x + fib[i + 1]y = 1 x *= X; y *= X; // x - k*fib[i + 1] >= 1, y + k*fib[i] >= 1の条件下xを最小化、yを最小化 if(x > 0) { // kを大きくする // x - 1 >= k * fib[i + 1] kmax = (x - 1) / fib[i + 1]; } else { // kを小さくする // 1 - x <= -k * fib[i + 1] kmax = -((1 - x + fib[i + 1] - 1) / fib[i + 1]); } int64_t a = (x - kmax * fib[i + 1]), b = (y + kmax * fib[i]); if(a >= 1 && b >= 1) { if(A > a || (A == a && B >= b)) { A = a; B = b; } } } cout << A << " " << B <<endl; } // B - A void back(int64_t bX, int64_t X, int64_t &A, int64_t &B) { int64_t tA, tB; A = tA = bX; B = tB = X; while(tB - tA >= 1) { int64_t cur = tB - tA; tB = A; tA = cur; if(tA < A || (tA == A && tB <= B)) { A = tA; B = tB; } } } bool check(int64_t bX, int64_t X, int64_t Y) { int64_t cur; while(bX <= Y) { if(bX == Y || X == Y) return true; cur = bX + X; bX = X; X = cur; } return false; } void solve(int64_t X, int64_t Y, int64_t Z) { int64_t A = numeric_limits<int64_t>::max(); int64_t B = numeric_limits<int64_t>::max(); vector<int64_t> tmp = {X, Y, Z}; sort(tmp.begin(), tmp.end()); X = tmp[0]; Y = tmp[1]; Z = tmp[2]; // Zに関するループ for(size_t k = 0; k < fib.size() - 1; k++) { // bX * fib[k] + X * fib[k + 1] = Z int64_t bX = Z - X * fib[k + 1]; if(bX <= 0) break; if(bX % fib[k] != 0) continue; bX /= fib[k]; if(check(bX, X, Y)) { long a, b; back(bX, X, a, b); if(a < A || (a == A && b < B)) { A = a; B = b; } } } if(A == numeric_limits<int64_t>::max()) { cout << -1 << endl; }else{ cout << A << " " << B << endl; } } int main() { fib.push_back(1); fib.push_back(1); for(size_t i = 2; fib[i - 2] <= 1000000000; i++) { fib.push_back(fib[i - 2] + fib[i - 1]); } int64_t X, Y, Z; cin >> X >> Y >> Z; if(X == Y && Y == Z) { solve_single(X); } else { solve(X, Y, Z); } }