首页 > 其他分享 >洛谷P1045 [NOIP2003 普及组] 麦森数

洛谷P1045 [NOIP2003 普及组] 麦森数

时间:2024-10-28 23:20:58浏览次数:7  
标签:10 洛谷 麦森数 int NOIP2003 12P 素数 次方 2P

形如 2P−12P−1 的素数称为麦森数,这时 PP 一定也是个素数。但反过来不一定,即如果 PP 是个素数,2P−12P−1 不一定也是素数。到 1998 年底,人们已找到了 37 个麦森数。最大的一个是 P=3021377P=3021377,它有 909526 位。麦森数有许多重要应用,它与完全数密切相关。

任务:输入 P(1000<P<3100000)P(1000<P<3100000),计算 2P−12P−1 的位数和最后 500500 位数字(用十进制高精度数表示)

输入格式

文件中只包含一个整数 P(1000<P<3100000)P(1000<P<3100000)

输出格式

第一行:十进制高精度数 2P−12P−1 的位数。

第 2∼112∼11 行:十进制高精度数 2P−12P−1 的最后 500500 位数字。(每行输出 5050 位,共输出 1010 行,不足 500500 位时高位补 00)

不必验证 2P−12P−1 与 PP 是否为素数。

输入输出样例

输入 #1复制

1279

输出 #1复制

386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

这个题目意思很明确,这里我们引入一个数学知识点  2的n次方位数=

N*log2  +1

2的n次方的个位数规律是:[ N*log2 ] +1 ],其中[ ]表示取整,log2=0.30102999566。例如,2的30次方的个位数是10,2的5次方的个位数是2,2的200次方的个位数是6112的幂次是由1×2的1次方乘以2的(n-1)次方来求得的,例如2的3次方=4,2的4次方=16,以此类推2

然后我们观察2^p-1里面这个 -1该如何处理呢?因为2的指数是的个位必然是不为0的偶数,所以直接减就好了,这也是很容易想到的,很容易想出这么一个代码

#include<stdio.h>
#include<math.h>
void f(int a[500]){
	for(int i=1;i<=500;i++){
		a[i]=a[i]*2;
	}
	for(int i=1;i<=500;i++){
		if(i!=500){
			if(a[i]>=10){
				a[i+1]=a[i]/10+a[i+1];
				a[i]=a[i]%10;
			}
		}else a[i]=a[i]%10;
	}
}
int main(){int p;
    scanf("%d",&p);
   int count=p*log10(2)+1;
	int a[501]={0};
	a[1]=1;
	for(int i=1;i<=p;i++)
	     f(a);
		 a[1]--;
		 printf("%d\n",count);
	for(int i=500;i>=1;i--){
		if((i-1)%50!=0)printf("%d",a[i]);
		else printf("%d\n",a[i]);			}
	return 0;
}

然而只对了6个测试点其他剩下4个测试点都是"TLE",很显然复杂度太高了,还有没有什么优化的方案呢,我冥思苦想不妨先判断p是奇数还是偶数,然后将其加速1倍,看看能不能行!(抱歉找不到代码了)

对了7个测试点!也就是说思路没错,既然能加速1倍那么为什么不能加速10倍!

                                                       最终AC代码

#include<stdio.h>
#include<math.h>
void f(int a[500],int k){
	for(int i=1;i<=500;i++){
		a[i]=a[i]*k;//加速10倍数 
	}
	for(int i=1;i<=500;i++){
		if(i!=500){
		a[i+1]=a[i]/10+a[i+1];	
		a[i]=a[i]%10;
			}
		else a[i]=a[i]%10;
	}
}
int main(){int p;
    scanf("%d",&p);
   int count=p*log10(2)+1;
	int a[501]={0};int k=pow(2,10);//加速预备 ,注意 
	a[1]=1;int p0=p%10;
	for(int i=1;i<=p/10;i++)
	     f(a,k);
	     while(p0--){for(int i=1;i<=500;i++){
		a[i]=a[i]*2;
	}//剩下需要乘的2,单独乘法!注意 
	for(int i=1;i<=500;i++){
		if(i!=500){
		a[i+1]=a[i]/10+a[i+1];	
		a[i]=a[i]%10;
			}
		else a[i]=a[i]%10;
	}	     	
		 }
		 a[1]--;
		 printf("%d\n",count);
	for(int i=500;i>=1;i--){
		if((i-1)%50!=0)printf("%d",a[i]);
		else printf("%d\n",a[i]);		
			}
	return 0;
}

实际上加速20倍也是可以的,后来我又想加速100倍,发现2的100次数位数太大了,int装不下……

学习的过程就是不断试错与探索的!

标签:10,洛谷,麦森数,int,NOIP2003,12P,素数,次方,2P
From: https://blog.csdn.net/Danies_yn/article/details/143315755

相关文章

  • 深度优先算法(DFS)洛谷P1683-入门
    虽然洛谷是有题解的,但是你如果直接看得懂题解,你也不会来看这篇文章..这些代码均是我记录自身成长的记录,有写的不好的地方请谅解!先上代码:#include<iostream>#include<vector>#include<iomanip>#include<cstdio>usingnamespacestd;constintN=30;charg[N......
  • CSP/信奥赛C++刷题训练:经典二分例题(2):洛谷P1678:烦恼的高考志愿
    CSP/信奥赛C++刷题训练:经典二分例题(2)烦恼的高考志愿题目背景计算机竞赛小组的神牛V神终于结束了高考,然而作为班长的他还不能闲下来,班主任老t给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是v神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计......
  • 洛谷 P5738 【深基7.例4】歌唱比赛 C语言 题解
    题目描述n(n≤100)n(n≤100) 名同学参加歌唱比赛,并接受 m(m≤20)m(m≤20) 名评委的评分,评分范围是 00 到 1010 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下 m−2m−2 个评分的平均数。请问得分最高的同学分数是多少?评分保留 22 位小数......
  • 20241024每日一题洛谷P1012
    普及-洛谷P1012拼数设有n个正整数,a1a2a3......an将它们联接成一排,相邻数字首尾相接,组成一个最大的整数输入:第一行有一个整数,表示数字个数n第二行有n个整数,表示给出的n个整数ai输出:一个正整数,表示最大的整数可以考虑两种路线:使用sort函数编辑cmp参数进行字符串......
  • C语言-详细讲解-洛谷P1255 数楼梯
    目录1.题目要求2.题目解读 1.如何计算走法数?2.如何解决大数加法,防止数据溢出1.进位的处理2.正序运算,倒序输出3.寻找结果中最高的非零位3.代码实现1.题目要求2.题目解读 一道非常经典的题目,简洁易懂,但需要一定的数学思维,难点如下:1.如何计算走法数?这里需要我......
  • 洛谷 P6628 [省选联考 2020 B 卷] 丁香之路 做题记录
    图论好题啊!首先我们枚举终点\(u\),看到一定要走完指定的\(m\)条边,很像一条欧拉路问题啊!但是现在问题是一个欧拉路问题,有两个点的度数是奇数,并不好做。我们不妨先从起点\(s\)向\(u\)连一条边,变成欧拉回路问题。现在我们需要做的是将度数为奇数的点加边使其变为偶数。方法是......
  • 洛谷 P1002 [NOIP2002 普及组] 过河卒
    你好,我是gwg725。洛谷账号:大号小号欢迎与我讨论。:)题目描述:棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1中的C点和P1,……,P8,卒不能通过......
  • 洛谷 P2680 [NOIP2015 提高组] 运输计划 做题记录
    首先题目要求最大的最小,我们二分答案,对于每个答案,我们筛出比它长的路径,找到它们最长的公共边,删掉后验证正确性即可。找公共边可以用树上差分来做,时间复杂度\(O(m\logn\logV)\),其中\(V\)是二分区间大小。你会发现你挂了一堆点,让我们来卡常:首先预处理出所有节点的\(dfn\),每......
  • P1040 [NOIP2003 提高组] 加分二叉树
    P1040[NOIP2003提高组]加分二叉树题目描述设一个\(n\)个节点的二叉树\(\text{tree}\)的中序遍历为\((1,2,3,\ldots,n)\),其中数字\(1,2,3,\ldots,n\)为节点编号。每个节点都有一个分数(均为正整数),记第\(i\)个节点的分数为\(d_i\),\(\text{tree}\)及它的每个子树都有一......
  • 洛谷 P3128 [USACO15DEC] Max Flow P 做题记录
    因为一次添加会对点和边都造成影响,而点一次能加两个,于是最大值一定在点上。由于只有一次询问,考虑树上差分。设一次询问给出的两点为\(x,y\),那么我们在\(x\)和\(y\)处分别加\(1\),在\(\operatorname{lca}(x,y)\)处减\(1\),因为该点本身也有增加,于是我们在它的父节点再减去......