2 条题解

  • 0
    @ 2026-6-19 22:52:51
    #include<iostream>
    using namespace std;
    typedef long long ll;
    int main(){
        ll n;
        cin>>n;
        if(n<=0){
            cout<<"-1"<<endl;
            return 0;
        }
        for(ll m=1;;m++){
            ll x=1;
            bool y=false;
            for(int i=0;i<m;i++){
                if(x>n/m){
                    y=true;
                    break;
                }
                x*=m;
            }
            if(y || x>n)break;
            if(x==n){
                cout<<m<<endl;
                return 0;
            }
        }
        cout<<"-1"<<endl;
        return 0;
    }
    
    • 0
      @ 2026-6-19 10:30:42

      📝 题目大意

      给定整数 BB1B10181 \le B \le 10^{18}),判断是否存在正整数 AA 满足 AA=BA^A = B,若存在则输出 AA,否则输出 1-1

      💡 解题思路

      1. 题目分析BB 最大为 101810^{18},而 AAA^A 增长极快。15154.38×1017101815^{15} \approx 4.38 \times 10^{17} \le 10^{18},而 16161.84×1019>101816^{16} \approx 1.84 \times 10^{19} > 10^{18}。因此满足条件的 AA 最多到 1515,枚举范围非常小。

      2. 算法推导

        • 枚举 AA111616(取 1616 作为安全上界,超出 BB 的会在计算中被剪枝掉)。
        • 对于每个 AA,通过循环计算 AAA^A:初始化 val = 1,乘 AAAA 次。
        • 在乘法过程中,一旦 val > B 就提前 break,避免溢出(long long 溢出会导致行为未定义)。
        • 如果最终 val == B,输出 AA 并结束程序。
        • 若枚举完所有 AA 均未匹配,输出 1-1
      3. 边界与细节

        • B=1B = 1 时,11=11^1 = 1,输出 11
        • 乘法过程中的溢出保护至关重要:long long 最大约 9.22×10189.22 \times 10^{18},大于 BB 的上限,但直接计算 161616^{16} 会溢出,所以必须在每次乘法后检查 val > B 并提前跳出。
        • 题目保证 B1B \ge 1,不存在 B=0B = 0 的情况。

      ⏱️ 复杂度分析

      • 时间复杂度O(1)O(1),枚举范围 A[1,16]A \in [1, 16],内层最多乘 1616 次,常数级操作。
      • 空间复杂度O(1)O(1),仅使用几个变量。

      💻 标准代码 (C++)

      #include <iostream>
      #include <cmath>
      using namespace std;
      int main() {
          long long B;
          cin >> B;
          // B ≤ 10^18,而 16^16 ≈ 1.84×10^19 > 10^18,所以 A 最多枚举到 16
          for (long long A = 1; A <= 16; A++) {
              long long val = 1;
              // 计算 A^A:将 A 自乘 A 次
              for (int i = 0; i < A; i++) {
                  val *= A;
                  // 若中间结果已经超过 B,提前剪枝,防止溢出
                  if (val > B) break; 
              }
              if (val == B) {
                  cout << A << endl;
                  return 0;
              }
          }
          // 枚举完所有可能的 A 仍未找到,输出 -1
          cout << -1 << endl;
          return 0;
      }
      
      • 1

      信息

      ID
      754
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      (无)
      递交数
      2
      已通过
      2
      上传者