結果

問題 No.219 巨大数の概算
ユーザー qwewe
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

#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
}
0