結果
問題 |
No.219 巨大数の概算
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:06:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 11 ms / 1,500 ms |
コード長 | 4,955 bytes |
コンパイル時間 | 678 ms |
コンパイル使用メモリ | 83,976 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-05-14 13:08:45 |
合計ジャッジ時間 | 3,983 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 51 |
ソースコード
#include <iostream> // Required for input/output operations (cin, cout) #include <vector> // Although not used, commonly included in C++ solutions #include <cmath> // Required for mathematical functions like log10l, powl, floorl // The main function where the program execution begins int main() { // Optimize input/output operations for speed. // std::ios_base::sync_with_stdio(false) disables synchronization with C standard streams. // std::cin.tie(NULL) unties cin from cout, allowing them to operate independently. std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N; // Declare variable N to store the number of test cases std::cin >> N; // Read the number of test cases from standard input // Loop through each test case for (int i = 0; i < N; ++i) { long long A_ll, B_ll; // Declare variables A_ll and B_ll to store the input parameters A and B as long long integers std::cin >> A_ll >> B_ll; // Read A and B for the current test case // Cast the input integers A and B to long double data type. // long double provides higher precision than double on many systems, which is crucial for handling potentially very large numbers and maintaining accuracy. long double A_ld = static_cast<long double>(A_ll); long double B_ld = static_cast<long double>(B_ll); // Calculate L = B * log10(A). This is the base-10 logarithm of A^B. // log10l is the long double version of the base-10 logarithm function. long double log10A = log10l(A_ld); // Calculate log10(A) long double L = B_ld * log10A; // Calculate L = B * log10(A) // Calculate Z, the integer part of L. Z represents the exponent in the scientific notation A^B = M * 10^Z. // floorl computes the largest integer value not greater than L, for long double type. long double L_floor = floorl(L); // Compute floor(L) as a long double // Cast the floor value to long long to store Z. Constraints guarantee Z >= 1 and fits in long long. long long Z_val = static_cast<long long>(L_floor); // Calculate F, the fractional part of L. F = L - floor(L). F will be in the range [0, 1). // This value corresponds to log10(M), where M is the mantissa. long double F = L - L_floor; // Calculate M = 10^F. M is the mantissa (significant digits part) of A^B in scientific notation. // M should theoretically be in the range [1, 10). // powl computes 10 raised to the power F for long double types. long double M = powl(10.0L, F); int X; // Declare variable X for the first significant digit (integer part of M) int Y; // Declare variable Y for the second significant digit (first decimal digit of M) // Handle a potential edge case caused by floating-point inaccuracies. // If M is computed as very close to 10.0 (e.g., 9.999...) or even slightly greater than or equal to 10.0, // it means the value effectively rounds up to the next power of 10. // This should be represented as 1.0 * 10^(Z+1). // We use a small tolerance (epsilon, here 1e-12L) for this check. 1e-12L is a conservative choice for long double precision. if (M >= 10.0L - 1e-12L) { // If M is effectively 10 or larger, set X=1, Y=0, and increment Z. X = 1; Y = 0; Z_val = Z_val + 1; // Adjust Z to the next higher power of 10 } else { // This is the standard case where M is computed to be in [1, 10 - epsilon). // Calculate X = floor(M). X will be an integer from 1 to 9. X = static_cast<int>(floorl(M)); // Calculate Y = floor((M - X) * 10). This extracts the first decimal digit of M. // We need to cast X back to long double for the subtraction to maintain precision. // Y will be an integer from 0 to 9. Y = static_cast<int>(floorl((M - static_cast<long double>(X)) * 10.0L)); // Safeguard checks: These conditions should theoretically not be met if the logic and floating-point arithmetic are behaving as expected. // If Y somehow is computed as 10 or more, cap it at 9 (consistent with truncation). if (Y >= 10) { Y = 9; } // If Y somehow is computed as less than 0, force it to 0. (This is highly unlikely as M >= 1 implies M-X >= 0). if (Y < 0) { Y = 0; } } // Output the calculated values X, Y, and Z for the current test case. // Values are separated by spaces, and each result is followed by a newline character. std::cout << X << " " << Y << " " << Z_val << "\n"; } return 0; // Return 0 to indicate successful program execution }