UVa 10398 The Golden Pentagon

题目描述

平面上可以用一系列边长按几何级数增长的等边三角形铺满,这些三角形满足一个多项式特征方程。 三角形的边框宽度可忽略不计,且这些三角形按大小排列构成了不同尺寸的五边形。

图中三角形按顺序编号为 1,2,3,…1, 2, 3, \ldots1,2,3, 。 本题的任务是:

  1. 如果第 III 个三角形的边长小于 10910^9109 ,则输出其向下取整的整数边长 LLL
  2. 如果第 III 个三角形的边长大于等于 10910^9109 ,则输出 LLL 在十进制下的位数 DDD

输入格式 : 输入包含 NNNN≤7300N \le 7300N7300 )行,每行包含一个浮点数 SSS0≤S≤100000 \le S \le 100000S10000 )表示第一个三角形的边长,和一个整数 III1≤I<1081 \le I < 10^81I<108 )。 输入以文件结束符终止。

输出格式 : 对每行输入,输出一行。 如果 L<109L < 10^9L<109 ,输出 LLL (向下取整整数); 否则输出 DDDLLL 的十进制位数)。

题目分析

关键信息提取

  1. 几何级数增长 : 三角形的边长按等比数列增长,设增长比例为 aaa
  2. 多项式特征方程 : 从几何关系可得方程 a5−a4−1=0a^5 - a^4 - 1 = 0a5a41=0
  3. 大数处理 : 当 III 很大时,边长可能超过 10910^9109 ,此时只需输出位数。
  4. 向下取整 : 题目要求输出 ⌊L⌋\lfloor L \rfloorL ,即 floor 函数的结果。

数学建模

设第一个三角形的边长为 SSS ,第 III 个三角形的边长为:
L=S⋅aI−1 L = S \cdot a^{I-1} L=SaI1
其中 aaa 是方程 a5−a4−1=0a^5 - a^4 - 1 = 0a5a41=0 的正实数根。

1. 求解增长比例 aaa

方程 a5−a4−1=0a^5 - a^4 - 1 = 0a5a41=0 可改写为 a5=a4+1a^5 = a^4 + 1a5=a4+1 ,这表明 aaa 是一个介于 111222 之间的实数。 我们可以使用牛顿迭代法求解:

牛顿迭代公式:
xn+1=xn−f(xn)f′(xn) x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} xn+1=xnf(xn)f(xn)
其中 f(x)=x5−x4−1f(x) = x^5 - x^4 - 1f(x)=x5x41f′(x)=5x4−4x3f'(x) = 5x^4 - 4x^3f(x)=5x44x3

取初始值 x0=1.5x_0 = 1.5x0=1.5 ,迭代至收敛即可得到 a≈1.324717957244746a \approx 1.324717957244746a1.324717957244746

实际上, aaa 就是著名的“塑胶数”(Plastic Number\texttt{Plastic Number}Plastic Number) ,是方程 x3−x−1=0x^3 - x - 1 = 0x3x1=0 的根。 验证一下:
a5−a4=(a3−a−1)⋅(a2+a+1)+1 a^5 - a^4 = (a^3 - a - 1) \cdot (a^2 + a + 1) + 1 a5a4=(a3a1)(a2+a+1)+1
由于 a3−a−1=0a^3 - a - 1 = 0a3a1=0 ,所以 a5−a4=1a^5 - a^4 = 1a5a4=1 ,满足原方程。

2. 计算策略
  • I=1I = 1I=1 时, L=SL = SL=S ,直接取整即可。
  • I>1I > 1I>1 时,需要计算 L=S⋅aI−1L = S \cdot a^{I-1}L=SaI1
    • 如果直接计算 aI−1a^{I-1}aI1 ,当 III 很大时(可达 10810^8108 ),会导致浮点数溢出。
    • 因此采用对数计算: 设 log⁡10L=log⁡10S+(I−1)⋅log⁡10a\log_{10} L = \log_{10} S + (I-1) \cdot \log_{10} alog10L=log10S+(I1)log10a
    • 如果 log⁡10L<9\log_{10} L < 9log10L<9 ,则 L<109L < 10^9L<109 ,计算 L=10log⁡10LL = 10^{\log_{10} L}L=10log10L 并取整。
    • 如果 log⁡10L≥9\log_{10} L \ge 9log10L9 ,则 L≥109L \ge 10^9L109 ,输出位数 D=⌊log⁡10L⌋+1D = \lfloor \log_{10} L \rfloor + 1D=log10L+1
3. 精度考虑

由于 III 很大,对数计算的精度足够。 使用 double 类型(约 15 位有效数字)可以满足题目要求。 牛顿迭代时设置收敛精度为 10−1210^{-12}1012

算法步骤

  1. 预处理 : 用牛顿法计算 aaalog⁡10a\log_{10} alog10a
  2. 处理每组输入
    • 如果 I=1I = 1I=1 ,直接处理 SSS
    • 否则计算 log⁡10L=log⁡10S+(I−1)⋅log⁡10a\log_{10} L = \log_{10} S + (I-1) \cdot \log_{10} alog10L=log10S+(I1)log10a
    • 如果 log⁡10L<9\log_{10} L < 9log10L<9 ,计算 L=S⋅aI−1L = S \cdot a^{I-1}L=SaI1 并输出 ⌊L⌋\lfloor L \rfloorL
    • 否则输出 D=⌊log⁡10L⌋+1D = \lfloor \log_{10} L \rfloor + 1D=log10L+1

代码实现

// The Golden Pentagon
// UVa ID: 10398
// Verdict: Accepted
// Submission Date: 2025-12-07
// UVa Run Time: 0.000s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net

#include <bits/stdc++.h>
using namespace std;

// 使用牛顿法求解方程 a^5 - a^4 - 1 = 0 的正实数根
double findGrowthRatio() {
    double a = 1.5;  // 初始猜测值
    double epsilon = 1e-12;
    for (int iter = 0; iter < 100; iter++) {
        double f = pow(a, 5) - pow(a, 4) - 1;
        double df = 5 * pow(a, 4) - 4 * pow(a, 3);
        double newA = a - f / df;
        if (fabs(newA - a) < epsilon) break;
        a = newA;
    }
    return a;
}

int main() {
    // 预先计算增长比例
    double a = findGrowthRatio();
    double log10A = log10(a);
    
    double s;
    int i;
    while (scanf("%lf %d", &s, &i) == 2) {
        if (i == 1) {
            // 第一个三角形
            long long len = (long long)floor(s);
            if (len < 1000000000) printf("%lld\n", len);
            else {
                int digits = (int)floor(log10(len)) + 1;
                printf("%d\n", digits);
            }
        } else {
            // 计算 log10(L) = log10(S) + (I-1)*log10(a)
            double log10L = log10(s) + (i - 1) * log10A;
            
            if (log10L < 9.0) {  // 10^9 = 1e9
                // 直接计算 L
                double L = s * pow(a, i - 1);
                long long len = (long long)floor(L);
                printf("%lld\n", len);
            } else {
                // 计算位数 D = floor(log10L) + 1
                int digits = (int)floor(log10L) + 1;
                printf("%d\n", digits);
            }
        }
    }
    return 0;
}

复杂度分析

  • 预处理 : 牛顿迭代常数次(约 10−2010-201020 次),时间复杂度 O(1)O(1)O(1)
  • 每次查询 : 仅进行常数次浮点数运算,时间复杂度 O(1)O(1)O(1)
  • 总复杂度O(N)O(N)O(N) ,其中 N≤7300N \le 7300N7300 ,完全可行。

总结

本题的关键在于:

  1. 识别几何关系 ,得到方程 a5−a4−1=0a^5 - a^4 - 1 = 0a5a41=0
  2. 使用牛顿法求解 增长比例 aaa ,得到塑胶数。
  3. 采用对数计算 避免大数溢出,同时满足精度要求。
  4. 注意边界情况 ,如 I=1I = 1I=1L≥109L \ge 10^9L109 时的特殊处理。

通过数学建模和数值计算,可以在常数时间内处理每个查询,高效解决问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值