zoukankan      html  css  js  c++  java
  • 洛谷P1045 麦森数

    题目描述

    (2^P - 1)的后五百位,且输出(2^P - 1)的位数,其中(1000<P<3100000)

    输出

    第一行:十进制高精度数 (2^{P}−1) 的位数。

    第2-11行:十进制高精度数 (2^{P}−1) 的最后500位数字。

    (每行输出50位,共输出10行,不足500位时高位补0)

    不必验证 (2^{P}−1)(P)是否为素数。

    分析

    1. 求数的位数

    假设(x = 2^P - 1),即求(x)的位数,因为(2^P)的最后一位一定大于1。

    所以(2^P)的位数与(x)的位数相同。

    (len = lg{x} + 1 = lg{2^P} + 1 = P*lg{2} + 1)

    例如100的长度为(lg100 + 1 = 2 +1 = 3)

    所以长度的计算方法为

    len = (int)(p * lg10(2)) + 1

    2. 两个高精度数的乘法

    const int N = 1e3 + 10; // 因为输出的长度为500, 500 + 500 = 1000
    
    vector<int> mul(vector<int> A, vector<int> B) {
        vector<int> C(N, 0);
        for (i = 0; i < 500; i++)
    		for (j = 0; j < 500; j++)
               	C[i + j] += C[i] * C[j];
       	for (j = 0; j < 500; j++) {
            C[j + 1] += C[j] / 10;
            C[j] = C[j] % 10;
        }
        return C;
    }
    

    3. 快速幂

    使用快速幂对空间复杂度进行优化

    int p; // p为输入的阶
    
    vector<int> t(N, 0); // 保存2^1 2^2 2^4
    vector<int> res(N, 0); // 结果
    t[0] = 2; // 初始化
    res[0] = 1;
    
    while (p) {
    	if (p & 1) // 如果p的2进制最后一个位为1
            res = mul(res, t);
        t = mul(t * t);
        p >>= 1;
    }
    

    4. 输出

        for (int i = 0, k = 499; i < 10; i++) {
            for (int j = 0; j < 50; j++, k--) {
                if (k) printf("%d", res[k]);
                else printf("%d", res[k] - 1);
            }
            puts("");
        }
    

    完整代码

    #include<cstdio>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    const int N = 1000 + 10;
    
    vector<int> mul(vector<int> &A, vector<int> &B) {
        vector<int> C(N, 0);
        for (int i = 0; i < 500; i++)
            for (int j = 0; j < 500; j++)
                C[i + j] += A[i] * B[j];
                // printf("%d ", i + j);
        for (int j = 0; j < 500; j++) {
            C[j + 1] += C[j] / 10;
            C[j] %= 10;
        }
        return C;
    }
    
    int main() {
        int p;
        scanf("%d", &p);
    
        vector<int> res(N, 0);
        vector<int> t(N, 0);
        t[0] = 2; res[0] = 1;
        
        printf("%d
    ", (int)(p * log10(2)) + 1);
    
        while (p) {
            if (p & 1)
                res = mul(res, t);
            t = mul(t, t);
            p >>= 1;
        }
    
    
        for (int i = 0, k = 499; i < 10; i++) {
            for (int j = 0; j < 50; j++, k--) {
                if (k) printf("%d", res[k]);
                else printf("%d", res[k] - 1);
            }
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    Android中ProgressDialog的应用
    Content的startActivity方法需添加FLAG_ACTIVITY_NEW_TASK flag
    android onKeydown
    8 个最优秀的 Android Studio 插件
    Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
    Android提供的LruCache类简介
    Android设计中的.9.png与Android Studio中的设置
    js实现双击后网页自己主动跑-------Day55
    Oracle经常使用函数
    《R实战》读书笔记三
  • 原文地址:https://www.cnblogs.com/mayapony/p/13976640.html
Copyright © 2011-2022 走看看